auto-deploy-demo/server/routes/auth.js

130 lines
3.2 KiB
JavaScript
Raw Permalink Normal View History

2026-02-23 06:31:59 +00:00
const express = require('express');
const bcrypt = require('bcryptjs');
const { generateToken, authMiddleware } = require('../middleware/auth');
const { getLockStatus, recordFailedAttempt, clearLock, getConfig } = require('../utils/loginLimiter');
const router = express.Router();
const users = [
{
id: '1',
username: 'admin',
password: bcrypt.hashSync('1221xian', 10)
}
];
router.post('/login', async (req, res) => {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).json({ error: '请输入用户名和密码' });
}
const lockStatus = getLockStatus(username);
if (lockStatus.locked) {
return res.status(429).json({
error: '登录已被临时限制',
locked: true,
remainingMs: lockStatus.remainingMs,
lockedUntil: lockStatus.lockedUntil
});
}
const user = users.find(u => u.username === username);
if (!user) {
const newLockStatus = recordFailedAttempt(username);
return res.status(401).json({
error: '用户名或密码错误',
attempts: newLockStatus.attempts,
maxAttempts: getConfig().maxAttempts
});
}
const isValidPassword = await bcrypt.compare(password, user.password);
if (!isValidPassword) {
const newLockStatus = recordFailedAttempt(username);
return res.status(401).json({
error: '用户名或密码错误',
attempts: newLockStatus.attempts,
maxAttempts: getConfig().maxAttempts,
locked: newLockStatus.locked,
remainingMs: newLockStatus.remainingMs,
lockedUntil: newLockStatus.lockedUntil
});
}
clearLock(username);
const token = generateToken(user.id);
res.json({
token,
user: {
id: user.id,
username: user.username
}
});
});
router.get('/lock-status/:username', (req, res) => {
const { username } = req.params;
if (!username) {
return res.status(400).json({ error: '用户名不能为空' });
}
const lockStatus = getLockStatus(username);
const config = getConfig();
res.json({
locked: lockStatus.locked,
attempts: lockStatus.attempts,
maxAttempts: config.maxAttempts,
remainingMs: lockStatus.remainingMs,
lockedUntil: lockStatus.lockedUntil
});
});
router.get('/verify', authMiddleware, (req, res) => {
const user = users.find(u => u.id === req.userId);
res.json({
user: {
id: user.id,
username: user.username
}
});
});
router.post('/change-password', authMiddleware, async (req, res) => {
const { currentPassword, newPassword } = req.body;
if (!currentPassword || !newPassword) {
return res.status(400).json({ error: '当前密码和新密码不能为空' });
}
if (newPassword.length < 6) {
return res.status(400).json({ error: '新密码长度至少6位' });
}
const user = users.find(u => u.id === req.userId);
if (!user) {
return res.status(404).json({ error: '用户不存在' });
}
const isValidPassword = await bcrypt.compare(currentPassword, user.password);
if (!isValidPassword) {
return res.status(401).json({ error: '当前密码错误' });
}
user.password = bcrypt.hashSync(newPassword, 10);
res.json({ message: '密码修改成功' });
});
module.exports = router;