const jwt = require("jsonwebtoken"); const logger = require("../utils/logger"); const { sendError } = require("../utils/response"); /** * JWT 认证中间件 * 验证请求头中的 token,如果有效则允许访问,否则返回 401 * 支持从 Authorization header 或 URL 查询参数(token)中获取 token */ const jwtAuth = (req, res, next) => { // 优先从请求头中获取 token let token = null; const authHeader = req.headers.authorization; if (authHeader) { // 支持两种格式: "Bearer token" 或 "token" token = authHeader.startsWith("Bearer ") ? authHeader.substring(7) : authHeader; } else if (req.query && req.query.token) { // 如果请求头中没有,尝试从 URL 查询参数中获取(用于文件下载等场景) token = req.query.token; } if (!token) { return sendError(res, "未提供认证令牌", "No token provided", 401); } const secret = process.env.JWT_SECRET || "your-secret-key"; jwt.verify(token, secret, (err, decoded) => { if (err) { if (err.name === "TokenExpiredError") { return sendError(res, "令牌已过期", "Token expired", 401); } if (err.name === "JsonWebTokenError") { return sendError(res, "无效的令牌", "Invalid token", 401); } logger.error("Token验证失败:", err); return sendError(res, "令牌验证失败", "Token verification failed", 401); } // 将解码后的用户信息添加到请求对象 req.user = decoded; next(); }); }; /** * 可选的 JWT 认证中间件 * 如果提供了有效 token 则解析用户信息,否则继续执行(不阻止请求) */ const optionalJwtAuth = (req, res, next) => { const authHeader = req.headers.authorization; if (!authHeader) { return next(); } const token = authHeader.startsWith("Bearer ") ? authHeader.substring(7) : authHeader; if (!token) { return next(); } const secret = process.env.JWT_SECRET || "your-secret-key"; jwt.verify(token, secret, (err, decoded) => { if (!err) { req.user = decoded; } next(); }); }; module.exports = { jwtAuth, optionalJwtAuth, };