peixue-dev/Archive/[一次性]游客模式401问题彻底修复方案-2026-02-01.md

187 lines
5.9 KiB
Markdown
Raw Normal View History

2026-02-28 17:26:03 +08:00
# 游客模式401问题彻底修复方案
**问题**: 后端返回401错误导致游客模式下无法看到课程数据
---
## 🔍 问题诊断
### 当前状态
1. ✅ 前端已配置游客白名单
2. ✅ 前端已添加 error.silent 检查
3. ✅ 后端WebMvcConfig已排除这些接口
4. ✅ JWT拦截器配置为无token时放行
5.**但后端仍然返回401错误**
### 控制台日志分析
```
[Request] 游客模式白名单接口业务码401静默失败不影响页面显示: /api/special-course/list
{code: 401, message: "未登录", data: {…}, silent: true}
```
**结论**: 后端确实返回了401错误说明有其他地方在检查用户登录状态
---
## 🎯 可能的原因
### 原因1: Service层检查了用户登录
某些Service方法可能使用了 `@CurrentUser` 注解或手动检查userId
### 原因2: 数据库中没有数据
即使接口正常,如果数据库中没有课程数据,也会显示空列表
### 原因3: Controller中有隐式的登录检查
虽然没有显式的权限注解但可能在方法内部检查了userId
---
## ✅ 解决方案
### 方案1: 检查并修复Service层推荐
#### 步骤1: 检查Service实现
查看这三个Service的实现确保没有强制要求userId
- `SpecialCourseService`
- `InterestCourseService`
- `AssessmentServiceService`
#### 步骤2: 修改Service方法
如果Service方法需要userId改为可选参数
```java
// 修改前
public List<Course> getCourseList(Long userId) {
if (userId == null) {
throw new BusinessException(401, "未登录");
}
// ...
}
// 修改后
public List<Course> getCourseList(Long userId) {
// userId可以为null游客模式下不影响查询
// ...
}
```
### 方案2: 创建测试数据
如果数据库中没有数据,创建一些测试数据:
```sql
-- 插入专项突破课程测试数据
INSERT INTO special_course (name, category, sub_category, description, price, duration, icon, status, sort_order, created_at, updated_at)
VALUES
('数学思维训练', 'math', '逻辑思维', '培养数学逻辑思维能力', 299.00, 60, '🧮', 1, 1, NOW(), NOW()),
('英语口语突破', 'english', '口语表达', '提升英语口语表达能力', 399.00, 90, '🗣️', 1, 2, NOW(), NOW()),
('阅读理解提升', 'language', '阅读理解', '提高阅读理解和分析能力', 199.00, 45, '📖', 1, 3, NOW(), NOW());
-- 插入兴趣培养课程测试数据
INSERT INTO interest_course (name, category, description, price, duration, icon, student_count, rating, status, created_at, updated_at)
VALUES
('钢琴入门', '音乐', '从零开始学习钢琴演奏', 599.00, 120, '🎹', 156, 4.8, 1, NOW(), NOW()),
('绘画启蒙', '美术', '培养绘画兴趣和基础技能', 399.00, 90, '🎨', 203, 4.7, 1, NOW(), NOW()),
('编程思维', '科技', '培养计算思维和编程能力', 699.00, 150, '💻', 89, 4.9, 1, NOW(), NOW());
-- 插入测评服务测试数据
INSERT INTO assessment_service (name, category, description, price, duration, icon, assessor_name, assessor_title, rating, appointment_count, status, created_at, updated_at)
VALUES
('学业能力测评', '学业', '全面评估学生学业水平', 299.00, 90, '📊', '张老师', '资深教育专家', 4.9, 234, 1, NOW(), NOW()),
('心理健康测评', '心理', '了解学生心理状态', 199.00, 60, '🧠', '李老师', '心理咨询师', 4.8, 178, 1, NOW(), NOW()),
('兴趣特长测评', '兴趣', '发现学生兴趣和特长', 249.00, 75, '🎯', '王老师', '职业规划师', 4.7, 145, 1, NOW(), NOW());
```
### 方案3: 后端直接返回空数据而不是401
修改Controller即使没有userId也返回空列表
```java
@GetMapping("/list")
public Result<List<Course>> getCourseList(@CurrentUser(required = false) Long userId, ...) {
// userId可以为null游客模式下返回公开课程
List<Course> courses = courseService.getCourseList(userId);
return Result.success(courses);
}
```
---
## 🔧 立即执行的修复步骤
### 步骤1: 检查数据库
运行脚本检查是否有数据:
```
Archive/[一次性]执行检查课程数据-2026-02-01.bat
```
### 步骤2: 如果没有数据,插入测试数据
创建并执行SQL脚本插入测试数据
### 步骤3: 重启后端服务
```
cd peidu/backend
mvn clean package -DskipTests
java -jar target/peidu-backend.jar
```
### 步骤4: 测试后端接口
```
Archive/[一次性]测试后端匿名访问-游客模式-2026-02-01.bat
```
### 步骤5: 如果还是401检查Service层
查看Service实现移除强制的userId检查
---
## 📝 预期结果
修复后:
- ✅ 游客访问课程列表 → 返回200和数据
- ✅ 前端正常显示课程列表
- ✅ 不再显示401错误
- ✅ 游客可以浏览所有公开课程
---
## 🚨 注意事项
1. **不要在公开接口中检查userId**
- 游客模式下userId为null是正常的
- 只在需要用户信息的接口中检查userId
2. **区分公开接口和私有接口**
- 公开接口:课程列表、详情、搜索等
- 私有接口:购买、收藏、我的课程等
3. **数据权限控制**
- 游客可以看到所有公开课程
- 但不能购买、不能看到价格敏感信息
---
## 💡 最佳实践
```java
@GetMapping("/list")
public Result<List<Course>> getCourseList(
@CurrentUser(required = false) Long userId, // ✅ required = false
@RequestParam(required = false) String category
) {
// 游客模式userId = null返回公开课程
// 登录模式userId != null可以返回个性化推荐
List<Course> courses = courseService.getCourseList(userId, category);
return Result.success(courses);
}
```
---
## 🎯 下一步
1. 先运行检查数据脚本,确认是否有数据
2. 如果没有数据,插入测试数据
3. 如果有数据但还是401检查Service层实现
4. 修改Service层移除强制的userId检查
5. 重启后端,测试接口