Files
AIGC/demo/LOGIN_FIX_SUMMARY.md
2025-11-13 17:01:39 +08:00

5.5 KiB
Raw Blame History

登录验证码403错误修复总结

问题描述

从宝塔面板日志和前端截图显示:

  • 请求地址:POST http://43.156.12.172/api/verification/email/send
  • 错误状态403 Forbidden
  • 问题:无法发送邮箱验证码

根本原因

  1. CORS跨域问题:后端 SecurityConfig 中没有配置允许 43.x.x.x IP段的跨域访问
  2. JWT过滤器问题:虽然配置了 permitAll(),但 JWT 过滤器仍然会处理所有请求,包括登录请求
  3. 前端token处理问题:登录请求也携带了 token导致认证流程混乱

修复方案

1. 后端修改

修改1SecurityConfig.java - CORS配置

文件路径: src/main/java/com/example/demo/config/SecurityConfig.java 修改位置: 第136-140行

添加对云服务器IP段的CORS支持

// 云服务器 IP 段43.x.x.x
"http://43.*.*.*:*",
"https://43.*.*.*:*",
"http://43.*.*.*",
"https://43.*.*.*",

修改2JwtAuthenticationFilter.java - 跳过公开路径

文件路径: src/main/java/com/example/demo/security/JwtAuthenticationFilter.java 修改位置: 第40-122行

添加公开路径列表JWT过滤器直接放行这些路径

// 定义不需要JWT验证的路径
String[] publicPaths = {
    "/api/auth/login",
    "/api/auth/login/email",
    "/api/auth/register",
    "/api/verification/",
    "/api/public/",
    "/api/email/",
    "/api/payments/alipay/notify",
    "/api/payments/alipay/return",
    "/swagger-ui",
    "/v3/api-docs",
    "/api-docs"
};

// 如果是公开路径直接放行不进行JWT验证
if (isPublicPath) {
    filterChain.doFilter(request, response);
    return;
}

2. 前端修改

修改1request.js - 请求拦截器

文件路径: frontend/src/api/request.js 修改位置: 第22-58行

登录相关请求不携带token

// 登录相关的接口不需要添加token
const loginUrls = [
  '/auth/login',
  '/auth/login/email',
  '/auth/register',
  '/verification/email/send',
  '/verification/email/verify',
  '/verification/email/dev-set',
  '/public/'
]

// 检查当前请求是否是登录相关接口
const isLoginRequest = loginUrls.some(url => config.url.includes(url))

if (!isLoginRequest) {
  // 非登录请求才添加Authorization头
  const token = sessionStorage.getItem('token')
  if (token && token !== 'null' && token.trim() !== '') {
    config.headers.Authorization = `Bearer ${token}`
  }
}

修改2request.js - 响应拦截器

文件路径: frontend/src/api/request.js 修改位置: 第60-177行

区分登录请求和非登录请求的错误处理:

  • 只有非登录请求出现401/302错误时才清除token并跳转
  • 登录请求的403错误显示具体错误信息不显示"权限不足"

部署步骤

1. 重新编译后端

cd C:\Users\UI\Desktop\AIGC\demo
mvn clean package -DskipTests

2. 停止旧的后端服务

在宝塔面板中停止当前运行的 Java 应用

3. 上传新的 JAR 包

target/demo-0.0.1-SNAPSHOT.jar 上传到服务器

4. 重启后端服务

在宝塔面板中启动 Java 应用,或使用命令:

java -jar demo-0.0.1-SNAPSHOT.jar

5. 重新编译前端(可选)

cd frontend
npm run build

6. 清除浏览器缓存

清除浏览器的缓存和 sessionStorage

验证步骤

  1. 访问登录页面:http://43.156.12.172
  2. 输入邮箱地址
  3. 点击"获取验证码"按钮
  4. 应该看到以下日志:
    JWT过滤器: 跳过公开路径 /api/verification/email/send
    
  5. 验证码应该成功发送不再出现403错误
  6. 输入验证码,完成登录
  7. 登录成功后所有后续请求都会自动携带token

技术要点

登录流程

  1. 登录前所有登录相关的请求发送验证码、登录、注册不携带token
  2. 登录中后端验证验证码生成JWT token返回
  3. 登录后前端保存token所有后续请求自动携带token进行认证

安全性

  • JWT过滤器只处理需要认证的请求
  • 公开路径登录、注册、验证码完全跳过JWT验证
  • CORS配置支持多种环境本地开发、内网、云服务器、ngrok

错误处理

  • 登录请求失败不会触发"重新登录"跳转
  • 非登录请求未认证才会跳转到登录页
  • 403错误根据请求类型显示不同提示

预期效果

修复后,登录流程应该如下:

  1. 访问登录页面正常
  2. 点击"获取验证码"成功发送不再403
  3. 输入验证码后登录成功
  4. 登录后所有功能正常使用
  5. Token过期或无效时自动跳转登录页

注意事项

  1. 确保后端和前端都重新编译部署
  2. 清除浏览器缓存避免旧代码影响
  3. 检查宝塔面板日志确认修改生效
  4. 如果还有问题,检查后端日志中的具体错误信息

相关文件清单

后端文件

  • src/main/java/com/example/demo/config/SecurityConfig.java
  • src/main/java/com/example/demo/security/JwtAuthenticationFilter.java

前端文件

  • frontend/src/api/request.js

配置文件

  • frontend/.env.production
  • frontend/vite.config.js

问题排查

如果修复后仍有问题,请检查:

  1. 后端日志:查看是否有异常堆栈
  2. CORS头:使用浏览器开发者工具查看响应头
  3. 请求头:确认登录请求没有 Authorization 头
  4. 网络:确认服务器防火墙允许访问
  5. 端口确认后端监听在正确的端口8080