admin/403权限问题修复说明.md
lvfengfree b92e1119ae fix: 修复菜单为空问题 - 移除后端过滤home路由的错误逻辑
- 修复RouteService中错误过滤home路由的问题
- 后端现在正确返回所有用户有权限的路由
- 添加设备管理相关功能(列表、在线监控、电源管理、远程监控)
- 添加详细的修复文档和重启脚本
- 更新权限配置脚本

问题根源:后端代码中有逻辑会过滤掉home路由,导致前端收到空数组,无法生成菜单
解决方案:移除过滤home路由的逻辑,让后端返回所有有权限的路由
2026-03-01 09:50:19 +08:00

5.6 KiB
Raw Blame History

403权限问题修复说明

问题原因

用户登录后跳转到403无权限页面主要原因有

  1. 缺少 home 路由权限:所有角色的 menus 字段都没有包含 home,导致登录后无法访问首页
  2. 路由名称格式不一致
    • R_USER 角色配置的是 my_device(下划线)
    • 但实际路由名称是 my-device(连字符)
    • 导致权限匹配失败
  3. 前端路由守卫检查 roles
    • 后端返回的路由 meta 中包含 roles 字段
    • 前端路由守卫会检查用户是否有对应的 roles
    • 但在动态路由模式下,后端已经根据用户角色过滤了路由
    • 前端不应该再次检查 roles否则会导致403错误

路由命名规则

  • 父路由使用连字符kebab-caseuser-managemy-devicemy-application
  • 子路由:使用下划线,如 user-manage_listmy-device_statusmy-application_apply

修复步骤

1. 运行数据库修复脚本

fix_403_complete.bat

或者手动执行SQL

mysql -u root -proot < fix_403_complete.sql

这个脚本会:

  • 为所有角色添加 home 路由权限
  • 修正路由名称格式(父路由用连字符,子路由用下划线)
  • 确保角色的 menus 字段与数据库中的路由名称一致

2. 重启后端服务

修复数据库后,必须重启 Spring Boot后端服务

cd backend
mvn spring-boot:run

或者在IDE中重启应用。

重要:后端代码已经修改,会自动移除路由 meta 中的 roles 字段,避免前端重复检查权限。

3. 清除浏览器缓存并重新登录

  • 按 Ctrl+Shift+Delete 清除浏览器缓存
  • 或者使用无痕模式/隐私模式
  • 退出登录
  • 重新登录测试

修复后的角色权限配置

R_SUPER超级管理员

拥有所有菜单权限:

  • home首页
  • device设备管理及所有子菜单
  • screen屏幕监控及所有子菜单
  • user-manage用户管理及所有子菜单
  • application使用申请及所有子菜单
  • system系统设置及所有子菜单
  • my-device我的设备及所有子菜单
  • my-application设备申请及所有子菜单

R_ADMIN管理员

除系统设置外的所有管理功能:

  • home首页
  • device设备管理及所有子菜单
  • screen屏幕监控及所有子菜单
  • user-manage用户管理列表和角色管理不包括权限管理
  • application使用申请及所有子菜单

R_USER普通用户

只能访问自己的设备和申请:

  • home首页
  • my-device我的设备及所有子菜单
  • my-application设备申请及所有子菜单

R_STU学生

只能访问首页:

  • home首页

验证修复

1. 检查数据库

-- 查看角色配置
SELECT role_code, role_name, menus FROM sys_role;

-- 查看路由配置
SELECT name, path, component FROM sys_route WHERE status = 1 ORDER BY order_num;

2. 测试登录

使用不同角色的账号登录测试:

  • admin/admin123R_SUPER + R_ADMIN应该能看到所有菜单
  • user/user123R_USER应该只能看到首页、我的设备、设备申请

3. 查看后端日志

登录后查看后端控制台输出,应该能看到类似以下的调试信息:

=== 用户路由权限调试 ===
用户ID: 1
用户角色: R_SUPER,R_ADMIN
查询到的角色数量: 2
角色: R_SUPER - 超级管理员
配置的菜单: home,device,device_list,...
允许访问的菜单: [home, device, device_list, ...]

常见问题

Q1: 修复后还是403

A: 请确保:

  1. 已重启后端服务
  2. 已清除浏览器缓存
  3. 已重新登录
  4. 检查后端日志确认菜单配置已更新

Q2: 某些菜单看不到?

A: 检查:

  1. 该菜单是否在角色的 menus 字段中
  2. 路由名称是否正确(父路由用连字符,子路由用下划线)
  3. 路由表中是否存在该路由且 status=1

Q3: 如何添加新菜单权限?

A:

  1. 在 sys_route 表中添加新路由
  2. 在 sys_role 表的 menus 字段中添加对应的路由名称
  3. 重启后端服务

技术细节

后端权限过滤逻辑

RouteService.getUserRoutes() 方法:

  1. 根据用户ID查询用户信息
  2. 获取用户的角色列表roles字段
  3. 查询这些角色的菜单配置menus字段
  4. 合并所有角色的菜单权限
  5. 自动添加父菜单(如果配置了子菜单)
  6. 从路由表中过滤出用户有权限的路由
  7. 移除路由 meta 中的 roles 字段(避免前端重复检查)
  8. 构建路由树并返回

前端路由处理

前端使用动态路由模式(VITE_AUTH_ROUTE_MODE=dynamic

  1. 登录成功后调用 /route/getUserRoutes 获取用户路由
  2. 前端根据返回的路由动态生成菜单
  3. 前端路由守卫检查逻辑
    • 检查路由的 meta.roles 字段
    • 如果路由有 roles 且用户没有对应角色跳转403
    • 在动态路由模式下后端已过滤路由meta 中不应包含 roles
  4. 如果访问未授权的路由会跳转到403页面

修复的关键点

后端修改RouteService.java

// 移除 roles 字段,因为后端已经根据角色过滤了路由
// 前端不需要再次检查 roles
meta.remove("roles");

这样前端路由守卫就不会检查 roles避免403错误。

相关文件

  • backend/src/main/java/com/soybean/admin/service/RouteService.java - 路由权限过滤逻辑
  • backend/src/main/java/com/soybean/admin/entity/Role.java - 角色实体
  • backend/src/main/resources/sql/init.sql - 数据库初始化脚本
  • fix_403_complete.sql - 权限修复脚本