5.9 KiB
5.9 KiB
游客模式401问题彻底修复方案
问题: 后端返回401错误,导致游客模式下无法看到课程数据
🔍 问题诊断
当前状态
- ✅ 前端已配置游客白名单
- ✅ 前端已添加 error.silent 检查
- ✅ 后端WebMvcConfig已排除这些接口
- ✅ JWT拦截器配置为无token时放行
- ❌ 但后端仍然返回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:
SpecialCourseServiceInterestCourseServiceAssessmentServiceService
步骤2: 修改Service方法
如果Service方法需要userId,改为可选参数:
// 修改前
public List<Course> getCourseList(Long userId) {
if (userId == null) {
throw new BusinessException(401, "未登录");
}
// ...
}
// 修改后
public List<Course> getCourseList(Long userId) {
// userId可以为null,游客模式下不影响查询
// ...
}
方案2: 创建测试数据
如果数据库中没有数据,创建一些测试数据:
-- 插入专项突破课程测试数据
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也返回空列表:
@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错误
- ✅ 游客可以浏览所有公开课程
🚨 注意事项
-
不要在公开接口中检查userId
- 游客模式下userId为null是正常的
- 只在需要用户信息的接口中检查userId
-
区分公开接口和私有接口
- 公开接口:课程列表、详情、搜索等
- 私有接口:购买、收藏、我的课程等
-
数据权限控制
- 游客可以看到所有公开课程
- 但不能购买、不能看到价格敏感信息
💡 最佳实践
@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);
}
🎯 下一步
- 先运行检查数据脚本,确认是否有数据
- 如果没有数据,插入测试数据
- 如果有数据但还是401,检查Service层实现
- 修改Service层,移除强制的userId检查
- 重启后端,测试接口