🐛 修复验证码Session问题 - 验证码过期Bug修复

## 问题描述
用户输入验证码后一直提示"验证码已过期"

## 根本原因
Session配置问题导致验证码无法正确保存和读取:
1. saveUninitialized: false 导致验证码请求时session不会被创建
2. 缺少 sameSite 属性导致某些情况下cookie无法正确传递

## 修复方案

### Session配置优化
- saveUninitialized: false → true (确保验证码请求时创建session)
- 添加 name: 'captcha.sid' (自定义session cookie名称)
- 添加 sameSite: 'lax' (防止CSRF同时确保同站请求携带cookie)

### 验证码生成API增强
- 添加 req.session.save() 确保session立即保存
- 添加调试日志输出SessionID和验证码内容

### 登录API调试
- 添加详细的验证码验证日志
- 输出SessionID、失败次数、验证码匹配情况
- 帮助快速定位问题

## 测试建议
1. 清除浏览器Cookie
2. 输错密码2次触发验证码
3. 查看后端日志确认SessionID一致
4. 输入正确验证码应该能通过验证

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-21 16:39:38 +00:00
parent 61c99ce5c0
commit 7ce9d95d44

View File

@@ -75,10 +75,12 @@ app.use(cookieParser());
app.use(session({
secret: process.env.SESSION_SECRET || 'your-session-secret-change-in-production',
resave: false,
saveUninitialized: false,
saveUninitialized: true, // 改为true确保验证码请求时创建session
name: 'captcha.sid', // 自定义session cookie名称
cookie: {
secure: process.env.COOKIE_SECURE === 'true',
httpOnly: true,
sameSite: 'lax', // 添加sameSite属性
maxAge: 10 * 60 * 1000 // 10分钟
}
}));
@@ -612,6 +614,15 @@ app.get('/api/captcha', (req, res) => {
req.session.captcha = captcha.text.toLowerCase();
req.session.captchaTime = Date.now();
// 保存session
req.session.save((err) => {
if (err) {
console.error('[验证码] Session保存失败:', err);
} else {
console.log('[验证码] 生成成功, SessionID:', req.sessionID, '验证码:', captcha.text);
}
});
res.type('svg');
res.send(captcha.data);
} catch (error) {
@@ -708,6 +719,8 @@ app.post('/api/login',
// 如果需要验证码,则验证验证码
if (needCaptcha) {
console.log('[登录验证] 需要验证码, SessionID:', req.sessionID, 'IP失败次数:', ipFailures, '用户名失败次数:', usernameFailures);
if (!captcha) {
return res.status(400).json({
success: false,
@@ -720,7 +733,10 @@ app.post('/api/login',
const sessionCaptcha = req.session.captcha;
const captchaTime = req.session.captchaTime;
console.log('[登录验证] Session验证码:', sessionCaptcha, '输入验证码:', captcha, 'Session时间:', captchaTime);
if (!sessionCaptcha || !captchaTime) {
console.log('[登录验证] 验证码不存在于Session中');
return res.status(400).json({
success: false,
message: '验证码已过期,请刷新验证码',
@@ -730,6 +746,7 @@ app.post('/api/login',
// 验证码有效期5分钟
if (Date.now() - captchaTime > 5 * 60 * 1000) {
console.log('[登录验证] 验证码已超过5分钟');
return res.status(400).json({
success: false,
message: '验证码已过期,请刷新验证码',
@@ -738,6 +755,7 @@ app.post('/api/login',
}
if (captcha.toLowerCase() !== sessionCaptcha) {
console.log('[登录验证] 验证码不匹配');
return res.status(400).json({
success: false,
message: '验证码错误',
@@ -745,6 +763,7 @@ app.post('/api/login',
});
}
console.log('[登录验证] 验证码验证通过');
// 验证通过后清除session中的验证码
delete req.session.captcha;
delete req.session.captchaTime;