接口鉴权
当你要给接口加权限点、排查“有菜单但点不了按钮”、或确认后端鉴权与前端路由/按钮如何协作时,优先看这篇。
youlai-think 采用经典的 RBAC(Role-Based Access Control) 权限模型,本文涵盖:
- 用户/角色/菜单/权限标识的关系与建模
- 后端接口鉴权的实现方式与常见问题排查
- 与前端按钮权限的联动约定
RBAC 模型
核心概念:用户 → 角色(多对多) → 菜单 → 权限标识
| 概念 | 说明 |
|---|---|
| 用户(User) | 通过角色间接获得权限 |
| 角色(Role) | 权限的集合,用户与权限的桥梁 |
| 菜单(Menu) | 系统功能入口,关联权限标识 |
| 权限标识(Perm) | 功能权限的唯一标识,如 sys:user:create |
接口鉴权
权限校验流程:
- 解析 Token 获取用户角色
- ROOT/ADMIN 角色直接放行
- 从 Redis 缓存获取角色权限列表
- 匹配权限标识(支持通配符
sys:user:*) - 无权限返回
403 A0301
控制器使用:通过中间件参数声明权限点
php
// 路由定义
Route::get('users', 'UserController/list')->middleware(PermMiddleware::class, 'sys:user:list');权限缓存机制
缓存结构:system:role:perms (Redis Hash)
Field: ADMIN Value: ["sys:user:*", "sys:role:*", ...]
Field: USER Value: ["sys:user:list", ...]缓存刷新:角色分配菜单、菜单权限修改、角色删除时自动刷新。
前端按钮权限
/me 接口响应:
json
{
"code": "00000",
"data": {
"userId": 1,
"username": "admin",
"roles": ["ADMIN", "USER"],
"perms": ["sys:user:list", "sys:user:create", "sys:user:update", "sys:user:delete"]
}
}自定义指令:
typescript
// v-has-perm 指令
<el-button v-has-perm="'sys:user:create'">新增用户</el-button>
<el-button v-has-perm="['sys:user:update', 'sys:user:delete']">操作</el-button>最佳实践
权限标识命名:采用三段式 模块:资源:操作
| 推荐 | 不推荐 | 问题 |
|---|---|---|
sys:user:create | userAdd | 缺少模块前缀 |
sys:role:delete | sys_user_add | 下划线风格混乱 |
monitor:server |
相关文件
| 文件路径 | 说明 |
|---|---|
app/system/service/RolePermService.php | 角色权限缓存服务 |
app/common/middleware/PermMiddleware.php | 权限校验中间件 |
app/common/middleware/AuthMiddleware.php | 认证中间件 |
app/system/controller/RoleController.php | 角色管理控制器 |
app/system/controller/MenuController.php | 菜单管理控制器 |
