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

187 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 游客模式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. 重启后端,测试接口