const jwt = require('jsonwebtoken'); const User = require('../models/User'); // JWT认证中间件 const authenticateToken = async (req, res, next) => { try { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN if (!token) { return res.status(401).json({ success: false, message: '访问令牌缺失', code: 'TOKEN_MISSING' }); } // 验证token const decoded = jwt.verify(token, process.env.JWT_SECRET); // 查找用户 const user = await User.findByPk(decoded.userId, { attributes: { exclude: ['password_hash'] } }); if (!user) { return res.status(401).json({ success: false, message: '用户不存在', code: 'USER_NOT_FOUND' }); } if (user.status !== 'active') { return res.status(401).json({ success: false, message: '用户账号已被禁用', code: 'USER_DISABLED' }); } // 将用户信息附加到请求对象 req.user = user; next(); } catch (error) { if (error.name === 'JsonWebTokenError') { return res.status(401).json({ success: false, message: '无效的访问令牌', code: 'INVALID_TOKEN' }); } else if (error.name === 'TokenExpiredError') { return res.status(401).json({ success: false, message: '访问令牌已过期', code: 'TOKEN_EXPIRED' }); } return res.status(500).json({ success: false, message: '认证服务错误', error: error.message }); } }; // 权限检查中间件 const requireRole = (roles) => { return (req, res, next) => { if (!req.user) { return res.status(401).json({ success: false, message: '用户未认证', code: 'USER_NOT_AUTHENTICATED' }); } const userRoles = Array.isArray(roles) ? roles : [roles]; if (!userRoles.includes(req.user.user_type)) { return res.status(403).json({ success: false, message: '权限不足', code: 'INSUFFICIENT_PERMISSIONS', requiredRoles: userRoles, userRole: req.user.user_type }); } next(); }; }; // 生成JWT token const generateToken = (user) => { const payload = { userId: user.id, username: user.username, userType: user.user_type }; return { accessToken: jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: process.env.JWT_EXPIRES_IN || '24h' }), refreshToken: jwt.sign( { userId: user.id }, process.env.JWT_SECRET + '_refresh', { expiresIn: process.env.JWT_REFRESH_EXPIRES_IN || '7d' } ) }; }; // 刷新token const refreshToken = async (req, res, next) => { try { const { refreshToken } = req.body; if (!refreshToken) { return res.status(400).json({ success: false, message: '刷新令牌缺失' }); } const decoded = jwt.verify(refreshToken, process.env.JWT_SECRET + '_refresh'); const user = await User.findByPk(decoded.userId, { attributes: { exclude: ['password_hash'] } }); if (!user || user.status !== 'active') { return res.status(401).json({ success: false, message: '无效的刷新令牌' }); } const tokens = generateToken(user); res.json({ success: true, message: '令牌刷新成功', data: tokens }); } catch (error) { return res.status(401).json({ success: false, message: '刷新令牌无效或已过期' }); } }; // 可选认证中间件(不强制要求登录) const optionalAuth = async (req, res, next) => { try { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (token) { const decoded = jwt.verify(token, process.env.JWT_SECRET); const user = await User.findByPk(decoded.userId, { attributes: { exclude: ['password_hash'] } }); if (user && user.status === 'active') { req.user = user; } } next(); } catch (error) { // 忽略错误,继续请求 next(); } }; module.exports = { authenticateToken, requireRole, generateToken, refreshToken, optionalAuth };