5.5 KiB
5.5 KiB
登录验证码403错误修复总结
问题描述
从宝塔面板日志和前端截图显示:
- 请求地址:
POST http://43.156.12.172/api/verification/email/send - 错误状态:403 Forbidden
- 问题:无法发送邮箱验证码
根本原因
- CORS跨域问题:后端 SecurityConfig 中没有配置允许 43.x.x.x IP段的跨域访问
- JWT过滤器问题:虽然配置了
permitAll(),但 JWT 过滤器仍然会处理所有请求,包括登录请求 - 前端token处理问题:登录请求也携带了 token,导致认证流程混乱
修复方案
1. 后端修改
修改1:SecurityConfig.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.*.*.*",
修改2:JwtAuthenticationFilter.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. 前端修改
修改1:request.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}`
}
}
修改2:request.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
验证步骤
- 访问登录页面:
http://43.156.12.172 - 输入邮箱地址
- 点击"获取验证码"按钮
- 应该看到以下日志:
JWT过滤器: 跳过公开路径 /api/verification/email/send - 验证码应该成功发送,不再出现403错误
- 输入验证码,完成登录
- 登录成功后,所有后续请求都会自动携带token
技术要点
登录流程
- 登录前:所有登录相关的请求(发送验证码、登录、注册)不携带token
- 登录中:后端验证验证码,生成JWT token返回
- 登录后:前端保存token,所有后续请求自动携带token进行认证
安全性
- JWT过滤器只处理需要认证的请求
- 公开路径(登录、注册、验证码)完全跳过JWT验证
- CORS配置支持多种环境(本地开发、内网、云服务器、ngrok)
错误处理
- 登录请求失败不会触发"重新登录"跳转
- 非登录请求未认证才会跳转到登录页
- 403错误根据请求类型显示不同提示
预期效果
修复后,登录流程应该如下:
- ✅ 访问登录页面正常
- ✅ 点击"获取验证码"成功发送(不再403)
- ✅ 输入验证码后登录成功
- ✅ 登录后所有功能正常使用
- ✅ Token过期或无效时自动跳转登录页
注意事项
- 确保后端和前端都重新编译部署
- 清除浏览器缓存避免旧代码影响
- 检查宝塔面板日志确认修改生效
- 如果还有问题,检查后端日志中的具体错误信息
相关文件清单
后端文件
src/main/java/com/example/demo/config/SecurityConfig.javasrc/main/java/com/example/demo/security/JwtAuthenticationFilter.java
前端文件
frontend/src/api/request.js
配置文件
frontend/.env.productionfrontend/vite.config.js
问题排查
如果修复后仍有问题,请检查:
- 后端日志:查看是否有异常堆栈
- CORS头:使用浏览器开发者工具查看响应头
- 请求头:确认登录请求没有 Authorization 头
- 网络:确认服务器防火墙允许访问
- 端口:确认后端监听在正确的端口(8080)