# 登录验证码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. 后端修改 #### 修改1:SecurityConfig.java - CORS配置 **文件路径**: `src/main/java/com/example/demo/config/SecurityConfig.java` **修改位置**: 第136-140行 添加对云服务器IP段的CORS支持: ```java // 云服务器 IP 段(43.x.x.x) "http://43.*.*.*:*", "https://43.*.*.*:*", "http://43.*.*.*", "https://43.*.*.*", ``` #### 修改2:JwtAuthenticationFilter.java - 跳过公开路径 **文件路径**: `src/main/java/com/example/demo/security/JwtAuthenticationFilter.java` **修改位置**: 第40-122行 添加公开路径列表,JWT过滤器直接放行这些路径: ```java // 定义不需要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. 前端修改 #### 修改1:request.js - 请求拦截器 **文件路径**: `frontend/src/api/request.js` **修改位置**: 第22-58行 登录相关请求不携带token: ```javascript // 登录相关的接口不需要添加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}` } } ``` #### 修改2:request.js - 响应拦截器 **文件路径**: `frontend/src/api/request.js` **修改位置**: 第60-177行 区分登录请求和非登录请求的错误处理: - 只有非登录请求出现401/302错误时才清除token并跳转 - 登录请求的403错误显示具体错误信息,不显示"权限不足" ## 部署步骤 ### 1. 重新编译后端 ```bash cd C:\Users\UI\Desktop\AIGC\demo mvn clean package -DskipTests ``` ### 2. 停止旧的后端服务 在宝塔面板中停止当前运行的 Java 应用 ### 3. 上传新的 JAR 包 将 `target/demo-0.0.1-SNAPSHOT.jar` 上传到服务器 ### 4. 重启后端服务 在宝塔面板中启动 Java 应用,或使用命令: ```bash java -jar demo-0.0.1-SNAPSHOT.jar ``` ### 5. 重新编译前端(可选) ```bash 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)