Spaces:
Sleeping
Sleeping
File size: 1,660 Bytes
4c025e9 006ee19 4c025e9 006ee19 4c025e9 006ee19 4c025e9 006ee19 4c025e9 006ee19 4c025e9 006ee19 4c025e9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
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 }; |