Files
vue-driven-cloud-storage/交接文档_验证码功能.md

16 KiB
Raw Blame History

玩玩云 - 验证码功能交接文档

创建时间2025年11月21日 项目名称vue-driven-cloud-storage玩玩云存储系统 功能:登录验证码功能实现与部署


📦 项目信息

Gitee仓库

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手动修复推荐

  1. SSH登录生产服务器
ssh root@你的服务器IP
  1. 找到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
  1. 编辑配置文件
vim /etc/nginx/conf.d/玩玩云.conf  # 替换为实际路径
  1. 找到 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;

    # 上传超时设置
    ...
}
  1. 测试并重载
# 测试配置
nginx -t

# 重新加载
nginx -s reload
  1. 验证修复
# 测试验证码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

测试验证码功能

  1. 访问登录页面
http://localhost:80
  1. 触发验证码
  • 输入任意用户名: test
  • 输入错误密码: wrong
  • 点击登录2次
  • 第3次尝试应该显示验证码
  1. 测试验证码验证
  • 输入验证码图片中的数字
  • 如果不清楚,点击图片刷新
  • 验证码应该能正常验证
  1. 检查浏览器
  • 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配置

项目信息


📅 后续工作计划

必须完成

  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管理

// 关键配置
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: '验证码错误'
    });
  }
}

🔐 安全注意事项

  1. SESSION_SECRET: 生产环境必须设置强随机值
  2. COOKIE_SECURE: HTTPS环境必须设置为true
  3. ALLOWED_ORIGINS: 必须配置CORS白名单
  4. JWT_SECRET: 必须设置强随机值
  5. 私人令牌: 不要泄露到公开仓库

文档版本: v1.0 最后更新: 2025-11-21 作者: Claude Code 状态: 代码已完成并推送 | ⚠️ 生产环境待修复