diff --git a/交接文档_验证码功能.md b/交接文档_验证码功能.md new file mode 100644 index 0000000..6bf1867 --- /dev/null +++ b/交接文档_验证码功能.md @@ -0,0 +1,685 @@ +# 玩玩云 - 验证码功能交接文档 + +> 创建时间:2025年11月21日 +> 项目名称:vue-driven-cloud-storage(玩玩云存储系统) +> 功能:登录验证码功能实现与部署 + +--- + +## 📦 项目信息 + +### Gitee仓库 +- **仓库地址**: https://gitee.com/yu-yon/vue-driven-cloud-storage.git +- **用户名**: `yu-yon` +- **私人令牌**: `54434786369b55e02e98f5ed6825a2e6` + +### Git配置 +```bash +git config user.name '喻勇祥' +git config user.email '237899745@qq.com' +``` + +### 克隆命令 +```bash +git clone https://gitee.com/yu-yon/vue-driven-cloud-storage.git +``` + +### 使用令牌推送 +```bash +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配置导致验证码无法保存 + +**修复内容**: +```javascript +// backend/server.js +session({ + saveUninitialized: true, // false → true + name: 'captcha.sid', + cookie: { + sameSite: 'lax' // 新增 + } +}) +``` + +### 3. `83773ef` - 🐛 修复验证码跨域Cookie传递问题 +**问题**: axios不携带credentials导致cookie无法传递 + +**修复内容**: +```javascript +// frontend/app.js mounted() +axios.defaults.withCredentials = true; +``` + +### 4. `fca00aa` - 🔄 更新前端版本号 +**问题**: 浏览器缓存旧版本js文件 + +**修复内容**: +```html + +app.js?v=20251110001 → app.js?v=20251121001 +``` + +### 5. `5f3fd38` - 🐛 修复Nginx Cookie传递问题 ⚠️ **最关键** +**问题**: Nginx反向代理默认不传递Cookie + +**修复内容**: +```nginx +# 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传递设置** + +**证据**: +```bash +curl -si https://cs.workyai.cn/api/captcha +HTTP/2 200 +❌ 缺少: Set-Cookie: captcha.sid=... +``` + +### 需要修复的步骤 + +#### 方法1:手动修复(推荐) + +1. **SSH登录生产服务器** +```bash +ssh root@你的服务器IP +``` + +2. **找到Nginx配置文件** +```bash +# 查找配置文件 +find /etc/nginx -name "*.conf" | xargs grep -l "workyai.cn" +# 或 +find /www/server -name "*.conf" | xargs grep -l "40001" + +# 输出示例: /etc/nginx/conf.d/玩玩云.conf +``` + +3. **编辑配置文件** +```bash +vim /etc/nginx/conf.d/玩玩云.conf # 替换为实际路径 +``` + +4. **找到 location /api 块** +```nginx +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; + + # 上传超时设置 + ... +} +``` + +5. **测试并重载** +```bash +# 测试配置 +nginx -t + +# 重新加载 +nginx -s reload +``` + +6. **验证修复** +```bash +# 测试验证码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:自动修复脚本 + +在服务器上运行: +```bash +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 +``` + +--- + +## 🧪 本地测试步骤 + +### 环境准备 +```bash +# 克隆项目 +git clone https://gitee.com/yu-yon/vue-driven-cloud-storage.git +cd vue-driven-cloud-storage + +# 安装后端依赖 +cd backend +npm install + +# 安装前端依赖(如需要) +cd ../frontend +# (前端通常无需安装,静态文件) +``` + +### 启动后端 +```bash +cd backend +node server.js + +# 或使用PM2 +pm2 start server.js --name backend + +# 查看日志 +pm2 logs backend +``` + +### 启动前端(使用简单HTTP服务器) +```bash +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(本地测试) +```bash +# 复制配置 +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 +``` + +### 测试验证码功能 + +1. **访问登录页面** +``` +http://localhost:80 +``` + +2. **触发验证码** +- 输入任意用户名: `test` +- 输入错误密码: `wrong` +- 点击登录2次 +- 第3次尝试应该显示验证码 + +3. **测试验证码验证** +- 输入验证码图片中的数字 +- 如果不清楚,点击图片刷新 +- 验证码应该能正常验证 + +4. **检查浏览器** +- F12 → Network +- 查看 `/api/captcha` 请求 +- Response Headers应该有: `Set-Cookie: captcha.sid=...` +- 查看 `/api/login` 请求 +- Request Headers应该有: `Cookie: captcha.sid=...` + +### 测试命令行 +```bash +# 测试验证码生成 +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配置 +```bash +# 查看完整配置 +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" {} \; +``` + +### 检查后端状态 +```bash +# 检查进程 +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 +```bash +# 本地测试 +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 + +--- + +## 📅 后续工作计划 + +### 必须完成 +1. ✅ 完成代码提交(已完成7个commit) +2. ⚠️ **修复生产环境Nginx配置**(待完成) +3. ⚠️ 验证生产环境验证码功能(待完成) + +### 建议完成 +1. 添加验证码样式优化 +2. 添加验证码错误次数限制 +3. 添加登录日志记录 +4. 考虑添加滑动验证码 + +### 优化建议 +1. 设置生产环境的SESSION_SECRET +2. 启用HTTPS时设置COOKIE_SECURE=true +3. 配置ALLOWED_ORIGINS白名单 +4. 定期清理失败的登录尝试记录 + +--- + +## 📋 验证清单 + +部署完成后,使用此清单验证: + +### 后端检查 +- [ ] 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管理 +```javascript +// 关键配置 +session({ + secret: 'your-secret', + resave: false, + saveUninitialized: true, // ⚠️ 必须为true + cookie: { + sameSite: 'lax', // ⚠️ 必须设置 + httpOnly: true, + maxAge: 10 * 60 * 1000 + } +}) +``` + +### Axios配置 +```javascript +// 全局配置 +axios.defaults.withCredentials = true; // ⚠️ 必须设置 +``` + +### Nginx配置 +```nginx +location /api { + # ... 其他配置 ... + + # ⚠️ 以下两行必须添加 + proxy_set_header Cookie $http_cookie; + proxy_pass_header Set-Cookie; +} +``` + +### 验证码生成 +```javascript +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(); +``` + +### 验证码验证 +```javascript +// 检查是否需要验证码 +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: '验证码错误' + }); + } +} +``` + +--- + +## 🔐 安全注意事项 + +1. **SESSION_SECRET**: 生产环境必须设置强随机值 +2. **COOKIE_SECURE**: HTTPS环境必须设置为true +3. **ALLOWED_ORIGINS**: 必须配置CORS白名单 +4. **JWT_SECRET**: 必须设置强随机值 +5. **私人令牌**: 不要泄露到公开仓库 + +--- + +**文档版本**: v1.0 +**最后更新**: 2025-11-21 +**作者**: Claude Code +**状态**: ✅ 代码已完成并推送 | ⚠️ 生产环境待修复