/** * 认证中间件 * @file auth.js * @description 处理用户认证和授权 */ const jwt = require('jsonwebtoken'); const { User, Role } = require('../models'); /** * 验证JWT令牌 * @param {Object} req 请求对象 * @param {Object} res 响应对象 * @param {Function} next 下一个中间件 */ const verifyToken = async (req, res, next) => { try { const token = req.header('Authorization')?.replace('Bearer ', ''); if (!token) { return res.status(401).json({ success: false, message: '访问被拒绝,未提供令牌' }); } const decoded = jwt.verify(token, process.env.JWT_SECRET); const user = await User.findByPk(decoded.id, { include: [{ model: Role, as: 'role' }] }); if (!user) { return res.status(401).json({ success: false, message: '令牌无效,用户不存在' }); } if (user.status !== 'active') { return res.status(401).json({ success: false, message: '账户已被禁用' }); } req.user = user; next(); } catch (error) { if (error.name === 'TokenExpiredError') { return res.status(401).json({ success: false, message: '令牌已过期' }); } else if (error.name === 'JsonWebTokenError') { return res.status(401).json({ success: false, message: '令牌无效' }); } else { console.error('认证中间件错误:', error); return res.status(500).json({ success: false, message: '服务器内部错误' }); } } }; /** * 检查用户角色权限 * @param {String|Array} roles 允许的角色 * @returns {Function} 中间件函数 */ const requireRole = (roles) => { return async (req, res, next) => { try { if (!req.user) { return res.status(401).json({ success: false, message: '请先登录' }); } const userRole = req.user.role; if (!userRole) { return res.status(403).json({ success: false, message: '用户角色未分配' }); } const allowedRoles = Array.isArray(roles) ? roles : [roles]; if (!allowedRoles.includes(userRole.name)) { return res.status(403).json({ success: false, message: '权限不足' }); } next(); } catch (error) { console.error('角色权限检查错误:', error); return res.status(500).json({ success: false, message: '服务器内部错误' }); } }; }; /** * 检查用户权限级别 * @param {Number} minLevel 最小权限级别 * @returns {Function} 中间件函数 */ const requireLevel = (minLevel) => { return async (req, res, next) => { try { if (!req.user) { return res.status(401).json({ success: false, message: '请先登录' }); } const userRole = req.user.role; if (!userRole || userRole.level < minLevel) { return res.status(403).json({ success: false, message: '权限级别不足' }); } next(); } catch (error) { console.error('权限级别检查错误:', error); return res.status(500).json({ success: false, message: '服务器内部错误' }); } }; }; /** * 可选认证中间件(不强制要求登录) * @param {Object} req 请求对象 * @param {Object} res 响应对象 * @param {Function} next 下一个中间件 */ const optionalAuth = async (req, res, next) => { try { const token = req.header('Authorization')?.replace('Bearer ', ''); if (token) { const decoded = jwt.verify(token, process.env.JWT_SECRET); const user = await User.findByPk(decoded.id, { include: [{ model: Role, as: 'role' }] }); if (user && user.status === 'active') { req.user = user; } } next(); } catch (error) { // 可选认证失败时不返回错误,继续执行 next(); } }; /** * 检查账户所有权 * @param {Object} req 请求对象 * @param {Object} res 响应对象 * @param {Function} next 下一个中间件 */ const checkAccountOwnership = async (req, res, next) => { try { const { accountId } = req.params; const userId = req.user.id; // 管理员可以访问所有账户 if (req.user.role && req.user.role.name === 'admin') { return next(); } const { Account } = require('../models'); const account = await Account.findOne({ where: { id: accountId, user_id: userId } }); if (!account) { return res.status(403).json({ success: false, message: '无权访问该账户' }); } req.account = account; next(); } catch (error) { console.error('账户所有权检查错误:', error); return res.status(500).json({ success: false, message: '服务器内部错误' }); } }; module.exports = { verifyToken, requireRole, requireLevel, optionalAuth, checkAccountOwnership };