165 lines
3.8 KiB
JavaScript
165 lines
3.8 KiB
JavaScript
|
|
const jwt = require('jsonwebtoken');
|
|||
|
|
const dbConnector = require('../utils/dbConnector');
|
|||
|
|
|
|||
|
|
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* JWT认证中间件
|
|||
|
|
* 验证token并附加用户信息到req对象
|
|||
|
|
*/
|
|||
|
|
const authMiddleware = async (req, res, next) => {
|
|||
|
|
try {
|
|||
|
|
const authHeader = req.headers.authorization;
|
|||
|
|
|
|||
|
|
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|||
|
|
return res.status(401).json({
|
|||
|
|
code: 401,
|
|||
|
|
message: '未提供有效的认证token',
|
|||
|
|
data: null
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const token = authHeader.substring(7); // 移除'Bearer '前缀
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// 验证token
|
|||
|
|
const decoded = jwt.verify(token, JWT_SECRET);
|
|||
|
|
|
|||
|
|
// 查询用户信息
|
|||
|
|
const users = await dbConnector.query(
|
|||
|
|
'SELECT id, username, phone, email, user_type, avatar_url, status FROM users WHERE id = ?',
|
|||
|
|
[decoded.userId]
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if (users.length === 0) {
|
|||
|
|
return res.status(401).json({
|
|||
|
|
code: 401,
|
|||
|
|
message: '用户不存在',
|
|||
|
|
data: null
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const user = users[0];
|
|||
|
|
|
|||
|
|
// 检查用户状态
|
|||
|
|
if (user.status !== 1) {
|
|||
|
|
return res.status(401).json({
|
|||
|
|
code: 401,
|
|||
|
|
message: '用户已被禁用',
|
|||
|
|
data: null
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 附加用户信息到请求对象
|
|||
|
|
req.user = {
|
|||
|
|
id: user.id,
|
|||
|
|
username: user.username,
|
|||
|
|
phone: user.phone,
|
|||
|
|
email: user.email,
|
|||
|
|
user_type: user.user_type,
|
|||
|
|
avatar_url: user.avatar_url
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
next();
|
|||
|
|
|
|||
|
|
} catch (jwtError) {
|
|||
|
|
if (jwtError.name === 'TokenExpiredError') {
|
|||
|
|
return res.status(401).json({
|
|||
|
|
code: 401,
|
|||
|
|
message: 'token已过期',
|
|||
|
|
data: null
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (jwtError.name === 'JsonWebTokenError') {
|
|||
|
|
return res.status(401).json({
|
|||
|
|
code: 401,
|
|||
|
|
message: '无效的token',
|
|||
|
|
data: null
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
throw jwtError;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('认证中间件错误:', error);
|
|||
|
|
return res.status(500).json({
|
|||
|
|
code: 500,
|
|||
|
|
message: '服务器内部错误',
|
|||
|
|
data: null
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 可选认证中间件
|
|||
|
|
* 如果提供了token就验证,不提供也不报错
|
|||
|
|
*/
|
|||
|
|
const optionalAuth = async (req, res, next) => {
|
|||
|
|
try {
|
|||
|
|
const authHeader = req.headers.authorization;
|
|||
|
|
|
|||
|
|
if (authHeader && authHeader.startsWith('Bearer ')) {
|
|||
|
|
const token = authHeader.substring(7);
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const decoded = jwt.verify(token, JWT_SECRET);
|
|||
|
|
|
|||
|
|
const users = await dbConnector.query(
|
|||
|
|
'SELECT id, username, phone, email, user_type, avatar_url, status FROM users WHERE id = ? AND status = 1',
|
|||
|
|
[decoded.userId]
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if (users.length > 0) {
|
|||
|
|
const user = users[0];
|
|||
|
|
req.user = {
|
|||
|
|
id: user.id,
|
|||
|
|
username: user.username,
|
|||
|
|
phone: user.phone,
|
|||
|
|
email: user.email,
|
|||
|
|
user_type: user.user_type,
|
|||
|
|
avatar_url: user.avatar_url
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
// token无效,但不阻止请求继续
|
|||
|
|
console.warn('可选认证失败:', error.message);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
next();
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('可选认证中间件错误:', error);
|
|||
|
|
next();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 管理员权限检查中间件
|
|||
|
|
*/
|
|||
|
|
const adminRequired = (req, res, next) => {
|
|||
|
|
if (!req.user) {
|
|||
|
|
return res.status(401).json({
|
|||
|
|
code: 401,
|
|||
|
|
message: '需要登录',
|
|||
|
|
data: null
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (req.user.user_type !== 'admin') {
|
|||
|
|
return res.status(403).json({
|
|||
|
|
code: 403,
|
|||
|
|
message: '需要管理员权限',
|
|||
|
|
data: null
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
next();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
module.exports = {
|
|||
|
|
authMiddleware,
|
|||
|
|
optionalAuth,
|
|||
|
|
adminRequired
|
|||
|
|
};
|