samlax12's picture
Upload 18 files
006ee19 verified
const jwt = require('jsonwebtoken');
const asyncHandler = require('express-async-handler');
const User = require('../models/User');
const logger = require('../utils/logger');
// 保护路由 - 验证 JWT Token
const protect = asyncHandler(async (req, res, next) => {
let token;
// 从 Authorization 头获取 token
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
try {
// 获取 token
token = req.headers.authorization.split(' ')[1];
logger.info(`验证令牌: ${token.substring(0, 15)}...`);
// 验证 token
const decoded = jwt.verify(token, process.env.JWT_SECRET);
logger.info(`令牌有效,用户ID: ${decoded.id}`);
// 获取用户并添加到请求对象中,不包含密码
req.user = await User.findById(decoded.id).select('-password');
if (!req.user) {
logger.warn(`令牌有效但用户不存在: ${decoded.id}`);
res.status(401);
throw new Error('未授权,用户不存在');
}
next();
} catch (error) {
logger.error(`令牌验证失败: ${error.message}`);
res.status(401);
throw new Error('未授权,token 无效');
}
} else {
logger.warn(`未提供认证令牌: ${req.originalUrl}`);
res.status(401);
throw new Error('未授权,未提供 token');
}
});
// 限制仅管理员访问
const admin = (req, res, next) => {
if (req.user && req.user.isAdmin) {
next();
} else {
res.status(403);
throw new Error('未授权,仅管理员可访问');
}
};
module.exports = { protect, admin };