rentease-backend/middleware/auth.js

100 lines
2.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const jwt = require('jsonwebtoken');
const User = require('../models/User');
// JWT 密钥
const JWT_SECRET = process.env.JWT_SECRET || 'rentease-secret-key';
// 生成 Token2小时有效期
const generateToken = (user) => {
return jwt.sign(
{
id: user.id,
username: user.username,
role: user.role?.code || user.role
},
JWT_SECRET,
{ expiresIn: '2h' }
);
};
// 验证 Token 中间件
const authMiddleware = async (req, res, next) => {
try {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({
code: 401,
message: '未提供认证令牌'
});
}
const token = authHeader.substring(7);
// 验证 Token
const decoded = jwt.verify(token, JWT_SECRET);
// 检查用户是否存在且状态正常
const user = await User.findOne({
where: {
id: decoded.id,
status: 'active'
},
attributes: ['id', 'username', 'nickname', 'roleId', 'status'],
include: [{
model: require('../models/Role'),
as: 'role',
attributes: ['id', 'name', 'code']
}]
});
if (!user) {
return res.status(401).json({
code: 401,
message: '用户不存在或已被禁用'
});
}
// 将用户信息附加到请求对象
req.user = user;
next();
} catch (error) {
if (error.name === 'TokenExpiredError') {
return res.status(401).json({
code: 401,
message: '登录已过期,请重新登录'
});
}
if (error.name === 'JsonWebTokenError') {
return res.status(401).json({
code: 401,
message: '无效的认证令牌'
});
}
return res.status(500).json({
code: 500,
message: '认证失败',
error: error.message
});
}
};
// 管理员权限检查中间件
const adminMiddleware = (req, res, next) => {
const userRole = req.user.role?.code || req.user.role;
if (userRole !== 'admin') {
return res.status(403).json({
code: 403,
message: '没有权限执行此操作'
});
}
next();
};
module.exports = {
generateToken,
authMiddleware,
adminMiddleware,
JWT_SECRET
};