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

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

191 lines
5.6 KiB
Markdown
Raw Permalink 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.

# 403权限问题修复说明
## 问题原因
用户登录后跳转到403无权限页面主要原因有
1. **缺少 home 路由权限**:所有角色的 menus 字段都没有包含 `home`,导致登录后无法访问首页
2. **路由名称格式不一致**
- R_USER 角色配置的是 `my_device`(下划线)
- 但实际路由名称是 `my-device`(连字符)
- 导致权限匹配失败
3. **前端路由守卫检查 roles**
- 后端返回的路由 meta 中包含 roles 字段
- 前端路由守卫会检查用户是否有对应的 roles
- 但在动态路由模式下,后端已经根据用户角色过滤了路由
- 前端不应该再次检查 roles否则会导致403错误
## 路由命名规则
- **父路由**使用连字符kebab-case`user-manage``my-device``my-application`
- **子路由**:使用下划线,如 `user-manage_list``my-device_status``my-application_apply`
## 修复步骤
### 1. 运行数据库修复脚本
```bash
fix_403_complete.bat
```
或者手动执行SQL
```bash
mysql -u root -proot < fix_403_complete.sql
```
这个脚本会:
- 为所有角色添加 `home` 路由权限
- 修正路由名称格式(父路由用连字符,子路由用下划线)
- 确保角色的 menus 字段与数据库中的路由名称一致
### 2. 重启后端服务
修复数据库后,**必须重启** Spring Boot后端服务
```bash
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. 检查数据库
```sql
-- 查看角色配置
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/admin123**R_SUPER + R_ADMIN应该能看到所有菜单
- **user/user123**R_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`
```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` - 权限修复脚本