131 lines
3.1 KiB
JavaScript
131 lines
3.1 KiB
JavaScript
const jwt = require('jsonwebtoken')
|
||
|
||
/**
|
||
* @swagger
|
||
* components:
|
||
* securitySchemes:
|
||
* bearerAuth:
|
||
* type: http
|
||
* scheme: bearer
|
||
* bearerFormat: JWT
|
||
* security:
|
||
* - bearerAuth: []
|
||
* responses:
|
||
* UnauthorizedError:
|
||
* description: 未授权访问
|
||
* content:
|
||
* application/json:
|
||
* schema:
|
||
* type: object
|
||
* properties:
|
||
* success:
|
||
* type: boolean
|
||
* example: false
|
||
* message:
|
||
* type: string
|
||
* example: 未授权访问
|
||
* ForbiddenError:
|
||
* description: 权限不足
|
||
* content:
|
||
* application/json:
|
||
* schema:
|
||
* type: object
|
||
* properties:
|
||
* success:
|
||
* type: boolean
|
||
* example: false
|
||
* message:
|
||
* type: string
|
||
* example: 权限不足
|
||
*/
|
||
|
||
// 从环境变量或配置中获取JWT密钥
|
||
const JWT_SECRET = process.env.JWT_SECRET || 'your_jwt_secret_key'
|
||
|
||
/**
|
||
* JWT认证中间件
|
||
* 验证请求中的JWT token,确认用户身份
|
||
* @param {Object} req - Express请求对象
|
||
* @param {Object} res - Express响应对象
|
||
* @param {Function} next - Express下一个中间件函数
|
||
*/
|
||
const authenticateJWT = (req, res, next) => {
|
||
// 从Authorization头中获取token
|
||
const authHeader = req.headers.authorization
|
||
|
||
if (!authHeader) {
|
||
return res.status(401).json({
|
||
success: false,
|
||
message: '未提供认证令牌'
|
||
})
|
||
}
|
||
|
||
// 提取token(格式:Bearer <token>)
|
||
const token = authHeader.split(' ')[1]
|
||
|
||
if (!token) {
|
||
return res.status(401).json({
|
||
success: false,
|
||
message: '无效的认证令牌格式'
|
||
})
|
||
}
|
||
|
||
try {
|
||
// 验证token
|
||
const decoded = jwt.verify(token, JWT_SECRET)
|
||
|
||
// 将解码的用户信息附加到请求对象中
|
||
req.user = decoded
|
||
|
||
// 继续处理请求
|
||
next()
|
||
} catch (error) {
|
||
console.error('JWT验证失败:', error)
|
||
|
||
if (error.name === 'TokenExpiredError') {
|
||
return res.status(401).json({
|
||
success: false,
|
||
message: '认证令牌已过期'
|
||
})
|
||
}
|
||
|
||
return res.status(401).json({
|
||
success: false,
|
||
message: '无效的认证令牌'
|
||
})
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 用户角色授权中间件
|
||
* 检查用户是否具有指定角色
|
||
* @param {Array<string>} allowedRoles - 允许访问的角色列表
|
||
* @returns {Function} Express中间件函数
|
||
*/
|
||
const authorizeRoles = (...allowedRoles) => {
|
||
return (req, res, next) => {
|
||
// 确保用户已通过认证
|
||
if (!req.user) {
|
||
return res.status(401).json({
|
||
success: false,
|
||
message: '未授权访问'
|
||
})
|
||
}
|
||
|
||
// 检查用户角色是否在允许列表中
|
||
if (!allowedRoles.includes(req.user.user_type)) {
|
||
return res.status(403).json({
|
||
success: false,
|
||
message: '权限不足'
|
||
})
|
||
}
|
||
|
||
// 用户具有所需角色,继续处理请求
|
||
next()
|
||
}
|
||
}
|
||
|
||
module.exports = {
|
||
authenticateJWT,
|
||
authorizeRoles
|
||
} |