75 lines
2.2 KiB
JavaScript
75 lines
2.2 KiB
JavaScript
const express = require('express');
|
|
const router = express.Router();
|
|
const jwt = require('jsonwebtoken');
|
|
const rateLimit = require('express-rate-limit');
|
|
const User = require('../models/User');
|
|
const UserRole = require('../models/UserRole');
|
|
const RolePerm = require('../models/RolePerm');
|
|
const { comparePassword } = require('../utils/password');
|
|
|
|
const loginLimiter = rateLimit({
|
|
windowMs: 15 * 60 * 1000,
|
|
max: 10,
|
|
message: { success: false, message: '登录尝试过于频繁' }
|
|
});
|
|
|
|
router.post('/login', loginLimiter, async (req, res) => {
|
|
try {
|
|
const { username, password } = req.body;
|
|
|
|
if (!username || !password) {
|
|
return res.status(400).json({ success: false, message: '用户名和密码不能为空' });
|
|
}
|
|
|
|
const user = await User.findOne({ username }).select('+password');
|
|
if (!user || user.status !== 'active') {
|
|
return res.status(401).json({ success: false, message: '用户名或密码错误' });
|
|
}
|
|
|
|
const isMatch = await comparePassword(password, user.password);
|
|
if (!isMatch) {
|
|
return res.status(401).json({ success: false, message: '用户名或密码错误' });
|
|
}
|
|
|
|
const userRole = await UserRole.findOne({ user: user._id }).populate('role');
|
|
if (!userRole) {
|
|
return res.status(403).json({ success: false, message: '该用户未分配角色' });
|
|
}
|
|
|
|
const rolePerms = await RolePerm.find({ role: userRole.role._id }).populate('permission');
|
|
const permissions = rolePerms.map(rp => rp.permission.permName);
|
|
|
|
const token = jwt.sign(
|
|
{
|
|
id: user._id,
|
|
username: user.username,
|
|
type: user.type,
|
|
role: userRole.role.roleName,
|
|
permissions,
|
|
jti: Math.random().toString(36)
|
|
},
|
|
process.env.JWT_SECRET,
|
|
{ expiresIn: process.env.JWT_EXPIRES_IN || '24h' }
|
|
);
|
|
|
|
res.json({
|
|
success: true,
|
|
data: {
|
|
id: user._id,
|
|
username: user.username,
|
|
name: user.name,
|
|
type: user.type,
|
|
role: userRole.role.roleName,
|
|
roleLabel: userRole.role.roleLabel,
|
|
permissions,
|
|
token
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error('Login error:', error);
|
|
res.status(500).json({ success: false, message: '服务器内部错误' });
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|