Files
rxthinkcmf-wiki/RXThinkCMF_Laravel13_NaiveVue/zh/guide/permission.md
T
2026-10-08 17:50:29 +08:00

102 lines
4.3 KiB
Markdown
Raw 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.
# 3.8 权限节点配置
:::tip 概述
权限节点用于控制用户能访问哪些接口。**菜单即权限**:菜单表的 `permission` 字段即权限编码,通过菜单管理界面配置,格式为 `sys:{模块名}:{操作}`;后端 `#[Permission]` 注解声明,`auth.jwt` 中间件统一校验。
:::
## Example 模块权限码
| 权限码 | 说明 | 对应接口 |
|--------|------|----------|
| `sys:example:page` | 案例演示分页列表 | `GET /api/example/page` |
| `sys:example:list` | 案例演示列表 | `GET /api/example/list` |
| `sys:example:detail` | 案例演示详情 | `GET /api/example/detail/{id}` |
| `sys:example:add` | 添加案例演示 | `POST /api/example/add` |
| `sys:example:update` | 修改案例演示 | `PUT /api/example/update` |
| `sys:example:delete` | 删除案例演示 | `DELETE /api/example/delete/{id}` |
| `sys:example:batchDelete` | 批量删除案例演示 | `DELETE /api/example/batchDelete` |
| `sys:example:import` | 导入案例演示 | `POST /api/example/import` |
| `sys:example:export` | 导出案例演示 | `GET /api/example/export` |
:::tip
控制器注解中声明的权限码(`#[Permission('sys:example:page', '示例分页')]`)必须与菜单管理中配置的 `permission` 字段**完全一致**,否则鉴权不通过。
:::
## 配置步骤
### 1. 添加目录节点
在系统菜单管理中添加一级目录(项目已内置「开发工具」目录,id=189,可直接复用):
| 字段 | 值 |
|------|-----|
| 菜单名称 | 开发工具 |
| 菜单类型 | 目录(type=0) |
| 路由地址 | /tool |
| 排序 | 50 |
### 2. 添加菜单节点(页面)
在目录下添加二级菜单(可导航页面,代码生成器创建的路径即为此格式):
| 字段 | 值 |
|------|-----|
| 菜单名称 | 案例演示 |
| 菜单类型 | 菜单/页面(type=0) |
| 路由地址 | /tool/example |
| 组件路径 | tool/example/index |
| 排序 | 1 |
### 3. 添加权限节点
在菜单下添加三级权限节点(type=1,`permission` 必填非空):
| 字段 | 值 | 权限标识 |
|------|-----|----------|
| 查看案例演示 | type=1 | sys:example:page |
| 添加案例演示 | type=1 | sys:example:add |
| 修改案例演示 | type=1 | sys:example:update |
| 删除案例演示 | type=1 | sys:example:delete |
| 导入案例演示 | type=1 | sys:example:import |
| 导出案例演示 | type=1 | sys:example:export |
### 4. 分配角色权限
在角色管理中,为角色勾选新增的权限节点(角色 → 菜单多对多,存于 `role_menu` 表)。
## 菜单类型说明
| type | 说明 | 前端行为 |
|------|------|----------|
| 0 | 菜单/目录(可导航) | 目录渲染为侧边栏分组,页面渲染为菜单项(需填 `component`) |
| 1 | 权限节点 | 不渲染,仅用于接口鉴权(`permission` 必填非空) |
## 权限校验流程
```text
1. 用户登录 → 获取用户角色(user_role 表)
2. 角色关联菜单 → 获取权限节点列表(role_menu 表,缓存于 Redis)
3. 请求接口 → auth.jwt 中间件读取控制器方法的 #[Permission] 注解(反射)
4. 检查权限码是否在用户权限列表中
├─ 在 → 放行,进入 tenant / demo / log.operation 中间件
├─ 不在 → 返回 {"code":403,"ok":false,"msg":"无访问权限"}
└─ 超级管理员(用户 ID=1)→ 跳过校验,直接放行
5. 菜单/角色菜单数据变更时,Observer 自动清除相关权限缓存
```
:::tip 两级校验
- **后端**:`#[Permission]` 注解 + `auth.jwt` 中间件(接口级,兜底);
- **前端**:`v-perm` 按钮指令(体验层,隐藏无权按钮)。
前端隐藏不等于安全——后端注解校验才是权限的最终防线。详见 [5.4 权限管理(RBAC)](/zh/core/rbac.html)。
:::
## 常见问题
| 现象 | 原因 | 处理 |
|------|------|------|
| 超管正常、普通角色 403 | 角色未分配该权限节点 | 角色管理勾选对应菜单/按钮 |
| 改了权限不生效 | 权限缓存未失效 | 重新保存角色菜单(`RoleMenuObserver` 自动清除权限缓存),或重新登录 |
| 注解写了仍 403 | 权限码与菜单 `permission` 不一致 | 逐字符比对(注意大小写与冒号) |
| 无 `#[Permission]` 的接口被拦截 | 接口放错位置 | 确认是否应为公开路由,移至中间件组外 |