83 lines
2.1 KiB
JavaScript
Raw Normal View History

2026-07-27 11:28:33 +08:00
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,
};