Appearance
RBAC 请求链路
从用户登录到按钮权限、接口鉴权的完整流程。
时序图
mermaid
sequenceDiagram
participant U as 用户浏览器
participant A as admin 前端
participant API as 后端
participant DB as MySQL
U->>A: 输入账号密码
A->>API: POST /api/v1/auth/login
API->>DB: 校验用户、查角色权限
API-->>A: accessToken + permissions + menus
A->>A: setupDynamicRoutes(menus)
A->>A: 渲染侧边栏、注册 v-permission
U->>A: 点击「用户管理」
A->>API: GET /api/v1/system/users (Bearer)
API->>API: JWT 校验 + hasAuthority
API->>DB: 查询用户列表
API-->>A: PageResult User[]步骤详解
1. 登录
- 前端:
authStore.login()→api.auth.login() - 后端:校验密码(BCrypt),返回
LoginResponse - 响应包含:
accessToken、refreshToken、user、roles、permissions、menus
2. Token 存储
- Web/Desktop:
localStorage(api-clientcreateLocalStorageTokenStorage) - 后续请求 Header:
Authorization: Bearer <accessToken>
3. 动态菜单与路由
menus为树形结构,后端已按用户 permissions 过滤- admin 包
setupDynamicRoutes()将菜单转为vue-router路由 - 组件路径如
system/users/index映射到views/system/users/index.vue
4. 路由守卫
- 无 Token → 跳转
/login - 有 Token 未初始化 →
fetchMe() - 路由
meta.permission不满足 →/403
5. 按钮权限
vue
<el-button v-permission="'system:user:create'">新建用户</el-button>v-permission 指令读取 authStore.permissions,无权限则移除 DOM。
6. 接口鉴权
| 后端 | 机制 |
|---|---|
| Java | @PreAuthorize("hasAuthority('system:user:list')") |
| Python | Depends(require_permission("system:user:list")) |
无权限返回 403:{ "code": 403, "message": "没有访问权限" }
7. Token 刷新
- accessToken 过期 → api-client 拦截 401 → 用 refreshToken 调
/auth/refresh - refresh 失败 →
onUnauthorized()→ 清 session 跳转登录
权限码列表(12 个)
text
system:user:list | create | update | delete
system:role:list | create | update | delete
system:menu:list | create | update | delete权限列表接口 GET /system/permissions 复用 system:role:list。