16 KiB
16 KiB
玩玩云 - 验证码功能交接文档
创建时间:2025年11月21日 项目名称:vue-driven-cloud-storage(玩玩云存储系统) 功能:登录验证码功能实现与部署
📦 项目信息
Gitee仓库
- 仓库地址: https://gitee.com/yu-yon/vue-driven-cloud-storage.git
- 用户名:
yu-yon - 私人令牌:
54434786369b55e02e98f5ed6825a2e6
Git配置
git config user.name '喻勇祥'
git config user.email '237899745@qq.com'
克隆命令
git clone https://gitee.com/yu-yon/vue-driven-cloud-storage.git
使用令牌推送
git push https://yu-yon:54434786369b55e02e98f5ed6825a2e6@gitee.com/yu-yon/vue-driven-cloud-storage.git master
✨ 本次功能更新概述
功能说明
添加登录验证码功能,提高系统安全性:
- 密码输错2次后自动显示验证码
- 4位纯数字验证码,可点击刷新
- 验证码有效期5分钟
- 基于IP和用户名双重防护
- 前台和后台登录均支持
技术实现
- 后端: Express + express-session + svg-captcha
- 前端: Vue 3 + axios
- 部署: Nginx反向代理 + Node.js后端
📝 本次提交记录
共提交了7个commit到Gitee master分支:
1. 61c99ce - ✨ 添加登录验证码功能
时间: 2025-11-21
后端改动:
- 安装依赖:
svg-captcha,express-session - 新增API:
GET /api/captcha(生成验证码) - 修改API:
POST /api/login(支持验证码验证) - 增强RateLimiter: 添加
getFailureCount()方法
前端改动:
- 登录表单添加验证码输入框(条件显示)
- 验证码图片展示和刷新功能
- 自动触发验证码显示逻辑
新增文档:
CAPTCHA_FEATURE.md- 详细功能文档CAPTCHA_README.md- 快速开始指南test_captcha.sh- 自动化测试脚本更新说明_验证码功能.txt- 中文说明
2. 7ce9d95 - 🐛 修复验证码Session问题
问题: Session配置导致验证码无法保存
修复内容:
// backend/server.js
session({
saveUninitialized: true, // false → true
name: 'captcha.sid',
cookie: {
sameSite: 'lax' // 新增
}
})
3. 83773ef - 🐛 修复验证码跨域Cookie传递问题
问题: axios不携带credentials导致cookie无法传递
修复内容:
// frontend/app.js mounted()
axios.defaults.withCredentials = true;
4. fca00aa - 🔄 更新前端版本号
问题: 浏览器缓存旧版本js文件
修复内容:
<!-- frontend/app.html -->
app.js?v=20251110001 → app.js?v=20251121001
5. 5f3fd38 - 🐛 修复Nginx Cookie传递问题 ⚠️ 最关键
问题: Nginx反向代理默认不传递Cookie
修复内容:
# nginx/nginx.conf - location /api 块中添加
proxy_set_header Cookie $http_cookie;
proxy_pass_header Set-Cookie;
6. 225c3a5 - 🔧 更新install.sh
问题: 安装脚本生成的Nginx配置缺少Cookie设置
修复内容:
- 修改install.sh的3处
location /api配置 - 添加自动修复脚本:
fix_install_sh.sh - 添加详细说明:
INSTALL_SH_UPDATE.md
7. 3ef0fa8 - 📖 添加验证码快速修复指南
新增文档: CAPTCHA_QUICK_FIX.md
🔧 完整的验证码工作原理
1. 验证码生成流程
浏览器 → GET /api/captcha
↓
后端生成验证码图片(SVG)
↓
后端创建session: req.session.captcha = "1234"
↓
后端返回: Set-Cookie: captcha.sid=xxx
↓
Nginx传递Cookie到浏览器
↓
浏览器保存cookie
2. 验证码验证流程
浏览器 → POST /api/login (带Cookie: captcha.sid=xxx)
↓
Nginx传递Cookie到后端
↓
后端读取session: req.session.captcha
↓
对比用户输入: captcha === session.captcha
↓
验证成功/失败
3. 配置依赖关系
验证码功能需要三层配置同时生效:
┌─────────────────────────────────────────────┐
│ 1. 前端配置 (frontend/app.js) │
│ axios.defaults.withCredentials = true │
│ → 确保请求携带cookie │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 2. Nginx配置 (nginx.conf) │
│ proxy_set_header Cookie $http_cookie │
│ proxy_pass_header Set-Cookie │
│ → 确保Cookie在Nginx层传递 │
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 3. 后端配置 (backend/server.js) │
│ session({ saveUninitialized: true }) │
│ → 确保session被创建和保存 │
└─────────────────────────────────────────────┘
缺少任何一层都会导致验证码失败!
⚠️ 当前存在的问题
生产环境验证码不工作
症状:
- 验证码一直提示"已过期"
- 测试发现:
curl -si https://cs.workyai.cn/api/captcha没有返回Set-Cookie
根本原因: 生产环境的Nginx配置没有应用Cookie传递设置
证据:
curl -si https://cs.workyai.cn/api/captcha
HTTP/2 200
❌ 缺少: Set-Cookie: captcha.sid=...
需要修复的步骤
方法1:手动修复(推荐)
- SSH登录生产服务器
ssh root@你的服务器IP
- 找到Nginx配置文件
# 查找配置文件
find /etc/nginx -name "*.conf" | xargs grep -l "workyai.cn"
# 或
find /www/server -name "*.conf" | xargs grep -l "40001"
# 输出示例: /etc/nginx/conf.d/玩玩云.conf
- 编辑配置文件
vim /etc/nginx/conf.d/玩玩云.conf # 替换为实际路径
- 找到 location /api 块
location /api {
proxy_pass http://localhost:40001;
...
proxy_set_header X-Forwarded-Proto $scheme;
# ⬇️ 在这一行后面添加3行 ⬇️
# Cookie传递配置(验证码session需要)
proxy_set_header Cookie $http_cookie;
proxy_pass_header Set-Cookie;
# 上传超时设置
...
}
- 测试并重载
# 测试配置
nginx -t
# 重新加载
nginx -s reload
- 验证修复
# 测试验证码API(应该返回Set-Cookie)
curl -si http://localhost:40001/api/captcha | grep -i "set-cookie"
# 期望输出:
# Set-Cookie: captcha.sid=s%3A...; Path=/; HttpOnly; SameSite=Lax
方法2:自动修复脚本
在服务器上运行:
cd /root/vue-driven-cloud-storage # 项目路径
# 拉取最新代码
git pull origin master
# 运行自动修复脚本
sudo bash << 'AUTO_FIX'
#!/bin/bash
set -e
echo "🔧 自动修复Nginx配置..."
# 查找配置文件
CONF=$(find /etc/nginx /www/server -name "*.conf" -exec grep -l "location /api" {} \; 2>/dev/null | grep -v backup | head -1)
if [[ -z "$CONF" ]]; then
echo "❌ 未找到配置文件"
exit 1
fi
echo "找到: $CONF"
# 备份
cp "$CONF" "${CONF}.backup.$(date +%Y%m%d%H%M%S)"
# 添加Cookie配置
if ! grep -q "proxy_set_header Cookie" "$CONF"; then
sed -i '/proxy_set_header X-Forwarded-Proto \$scheme;/a\
\
# Cookie传递配置(验证码session需要)\
proxy_set_header Cookie $http_cookie;\
proxy_pass_header Set-Cookie;' "$CONF"
echo "✅ 已添加Cookie配置"
else
echo "✅ Cookie配置已存在"
fi
# 测试并重载
nginx -t && nginx -s reload
echo "✅ 修复完成!"
echo ""
echo "验证修复:"
curl -si http://localhost:40001/api/captcha | grep -i "set-cookie"
AUTO_FIX
🧪 本地测试步骤
环境准备
# 克隆项目
git clone https://gitee.com/yu-yon/vue-driven-cloud-storage.git
cd vue-driven-cloud-storage
# 安装后端依赖
cd backend
npm install
# 安装前端依赖(如需要)
cd ../frontend
# (前端通常无需安装,静态文件)
启动后端
cd backend
node server.js
# 或使用PM2
pm2 start server.js --name backend
# 查看日志
pm2 logs backend
启动前端(使用简单HTTP服务器)
cd frontend
# 方法1: Python
python3 -m http.server 3000
# 方法2: Node.js http-server
npx http-server -p 3000
# 方法3: Nginx(推荐,模拟生产环境)
# 使用项目中的 nginx/nginx.conf
配置Nginx(本地测试)
# 复制配置
sudo cp nginx/nginx.conf /etc/nginx/conf.d/玩玩云-本地.conf
# 修改配置中的路径
sudo vim /etc/nginx/conf.d/玩玩云-本地.conf
# 修改 root 路径为你的实际路径
# 修改 proxy_pass 为 http://localhost:40001
# 测试并重载
sudo nginx -t
sudo nginx -s reload
测试验证码功能
- 访问登录页面
http://localhost:80
- 触发验证码
- 输入任意用户名:
test - 输入错误密码:
wrong - 点击登录2次
- 第3次尝试应该显示验证码
- 测试验证码验证
- 输入验证码图片中的数字
- 如果不清楚,点击图片刷新
- 验证码应该能正常验证
- 检查浏览器
- F12 → Network
- 查看
/api/captcha请求 - Response Headers应该有:
Set-Cookie: captcha.sid=... - 查看
/api/login请求 - Request Headers应该有:
Cookie: captcha.sid=...
测试命令行
# 测试验证码生成
curl -vi http://localhost:40001/api/captcha | grep -i "set-cookie"
# 完整流程测试
# 1. 生成验证码并保存cookie
curl -s http://localhost:40001/api/captcha -c cookies.txt > /dev/null
# 2. 查看cookie
cat cookies.txt
# 3. 使用cookie登录
curl -v http://localhost:40001/api/login \
-b cookies.txt \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123","captcha":"1234"}'
# 清理
rm cookies.txt
📂 重要文件清单
后端文件
backend/
├── server.js # ✅ 已修改 - session配置、验证码API
├── package.json # ✅ 已修改 - 新增依赖
├── package-lock.json # ✅ 已修改
├── auth.js # 无修改
└── database.js # 无修改
前端文件
frontend/
├── app.html # ✅ 已修改 - 验证码UI、版本号
└── app.js # ✅ 已修改 - withCredentials、验证码逻辑
Nginx配置
nginx/
└── nginx.conf # ✅ 已修改 - Cookie传递配置
部署脚本
install.sh # ✅ 已修改 - 3处Cookie配置
fix_install_sh.sh # ✅ 新增 - 自动修复脚本
文档
CAPTCHA_FEATURE.md # ✅ 新增 - 详细功能文档
CAPTCHA_README.md # ✅ 新增 - 快速开始
CAPTCHA_QUICK_FIX.md # ✅ 新增 - 快速修复指南
INSTALL_SH_UPDATE.md # ✅ 新增 - install.sh修改说明
更新说明_验证码功能.txt # ✅ 新增 - 中文说明
test_captcha.sh # ✅ 新增 - 测试脚本
交接文档_验证码功能.md # ✅ 本文档
🔍 问题诊断工具
检查Nginx配置
# 查看完整配置
nginx -T | grep -A 30 "location /api"
# 检查Cookie配置
nginx -T | grep -i "proxy_set_header cookie"
# 查找配置文件
find /etc/nginx -name "*.conf" -exec grep -l "workyai.cn" {} \;
检查后端状态
# 检查进程
ps aux | grep "node.*server"
# 检查端口
netstat -tlnp | grep 40001
# 检查依赖
cd backend && npm list | grep -E "(session|captcha)"
# 查看日志
pm2 logs backend
# 或
tail -f backend/logs/error.log
测试验证码API
# 本地测试
curl -vi http://localhost:40001/api/captcha
# 远程测试
curl -vi https://cs.workyai.cn/api/captcha
# 完整测试
bash test_captcha.sh
📞 联系方式
Git配置
- 用户名: 喻勇祥
- 邮箱: 237899745@qq.com
项目信息
- Gitee: https://gitee.com/yu-yon
- 项目: vue-driven-cloud-storage
📅 后续工作计划
必须完成
- ✅ 完成代码提交(已完成7个commit)
- ⚠️ 修复生产环境Nginx配置(待完成)
- ⚠️ 验证生产环境验证码功能(待完成)
建议完成
- 添加验证码样式优化
- 添加验证码错误次数限制
- 添加登录日志记录
- 考虑添加滑动验证码
优化建议
- 设置生产环境的SESSION_SECRET
- 启用HTTPS时设置COOKIE_SECURE=true
- 配置ALLOWED_ORIGINS白名单
- 定期清理失败的登录尝试记录
📋 验证清单
部署完成后,使用此清单验证:
后端检查
- express-session依赖已安装
- svg-captcha依赖已安装
- server.js包含session配置
- server.js包含验证码API
- server.js包含验证码验证逻辑
- 后端服务正常运行
前端检查
- app.html包含验证码UI
- app.html版本号已更新
- app.js包含withCredentials配置
- app.js包含验证码逻辑
- 浏览器缓存已清除
Nginx检查
- location /api包含proxy_set_header Cookie
- location /api包含proxy_pass_header Set-Cookie
- nginx -t 测试通过
- nginx已重新加载
功能测试
- 第1-2次登录失败不显示验证码
- 第3次登录失败显示验证码
- 验证码图片可以正常显示
- 点击验证码可以刷新
- 输入正确验证码可以通过验证
- 输入错误验证码提示错误
- 管理员登录也受验证码保护
- 登录成功后验证码自动隐藏
API测试
- GET /api/captcha 返回SVG图片
- GET /api/captcha 返回Set-Cookie响应头
- POST /api/login 接收captcha参数
- POST /api/login 验证验证码
- POST /api/login 携带Cookie请求头
🎓 技术要点总结
Session管理
// 关键配置
session({
secret: 'your-secret',
resave: false,
saveUninitialized: true, // ⚠️ 必须为true
cookie: {
sameSite: 'lax', // ⚠️ 必须设置
httpOnly: true,
maxAge: 10 * 60 * 1000
}
})
Axios配置
// 全局配置
axios.defaults.withCredentials = true; // ⚠️ 必须设置
Nginx配置
location /api {
# ... 其他配置 ...
# ⚠️ 以下两行必须添加
proxy_set_header Cookie $http_cookie;
proxy_pass_header Set-Cookie;
}
验证码生成
const svgCaptcha = require('svg-captcha');
const captcha = svgCaptcha.create({
size: 4, // 4位数字
noise: 2, // 干扰线
color: true, // 彩色
charPreset: '0123456789' // 只用数字
});
req.session.captcha = captcha.text.toLowerCase();
req.session.captchaTime = Date.now();
验证码验证
// 检查是否需要验证码
const needCaptcha = ipFailures >= 2 || usernameFailures >= 2;
if (needCaptcha) {
// 验证验证码
const sessionCaptcha = req.session.captcha;
const captchaTime = req.session.captchaTime;
// 检查过期(5分钟)
if (Date.now() - captchaTime > 5 * 60 * 1000) {
return res.status(400).json({
success: false,
message: '验证码已过期'
});
}
// 验证是否匹配
if (captcha.toLowerCase() !== sessionCaptcha) {
return res.status(400).json({
success: false,
message: '验证码错误'
});
}
}
🔐 安全注意事项
- SESSION_SECRET: 生产环境必须设置强随机值
- COOKIE_SECURE: HTTPS环境必须设置为true
- ALLOWED_ORIGINS: 必须配置CORS白名单
- JWT_SECRET: 必须设置强随机值
- 私人令牌: 不要泄露到公开仓库
文档版本: v1.0 最后更新: 2025-11-21 作者: Claude Code 状态: ✅ 代码已完成并推送 | ⚠️ 生产环境待修复