9 lines
8.6 KiB
JavaScript
9 lines
8.6 KiB
JavaScript
import{_ as e,o as d,c as a,a2 as o}from"./chunks/framework.B-QBKwc1.js";const m=JSON.parse('{"title":"权限节点配置","description":"权限节点用于控制用户能访问哪些接口。","frontmatter":{},"headers":[],"relativePath":"zh/guide/permission.md","filePath":"zh/guide/permission.md"}'),s={name:"zh/guide/permission.md"};function r(l,t,p,i,c,n){return d(),a("div",null,[...t[0]||(t[0]=[o(`<h1 id="_3-8-权限节点配置" tabindex="-1">3.8 权限节点配置 <a class="header-anchor" href="#_3-8-权限节点配置" aria-label="Permalink to "3.8 权限节点配置""></a></h1><div class="tip custom-block"><p class="custom-block-title">概述</p><p>权限节点用于控制用户能访问哪些接口。<strong>菜单即权限</strong>:菜单表的 <code>permission</code> 字段即权限编码,通过菜单管理界面配置,格式为 <code>sys:{模块名}:{操作}</code>;后端 <code>#[Permission]</code> 注解声明,<code>auth.jwt</code> 中间件统一校验。</p></div><h2 id="Example-模块权限码" tabindex="-1">Example 模块权限码 <a class="header-anchor" href="#Example-模块权限码" aria-label="Permalink to "Example 模块权限码""></a></h2><table tabindex="0"><thead><tr><th>权限码</th><th>说明</th><th>对应接口</th></tr></thead><tbody><tr><td><code>sys:example:page</code></td><td>案例演示分页列表</td><td><code>GET /api/example/page</code></td></tr><tr><td><code>sys:example:list</code></td><td>案例演示列表</td><td><code>GET /api/example/list</code></td></tr><tr><td><code>sys:example:detail</code></td><td>案例演示详情</td><td><code>GET /api/example/detail/{id}</code></td></tr><tr><td><code>sys:example:add</code></td><td>添加案例演示</td><td><code>POST /api/example/add</code></td></tr><tr><td><code>sys:example:update</code></td><td>修改案例演示</td><td><code>PUT /api/example/update</code></td></tr><tr><td><code>sys:example:delete</code></td><td>删除案例演示</td><td><code>DELETE /api/example/delete/{id}</code></td></tr><tr><td><code>sys:example:batchDelete</code></td><td>批量删除案例演示</td><td><code>DELETE /api/example/batchDelete</code></td></tr><tr><td><code>sys:example:import</code></td><td>导入案例演示</td><td><code>POST /api/example/import</code></td></tr><tr><td><code>sys:example:export</code></td><td>导出案例演示</td><td><code>GET /api/example/export</code></td></tr></tbody></table><div class="tip custom-block"><p class="custom-block-title">TIP</p><p>控制器注解中声明的权限码(<code>#[Permission('sys:example:page', '示例分页')]</code>)必须与菜单管理中配置的 <code>permission</code> 字段<strong>完全一致</strong>,否则鉴权不通过。</p></div><h2 id="配置步骤" tabindex="-1">配置步骤 <a class="header-anchor" href="#配置步骤" aria-label="Permalink to "配置步骤""></a></h2><h3 id="_1-添加目录节点" tabindex="-1">1. 添加目录节点 <a class="header-anchor" href="#_1-添加目录节点" aria-label="Permalink to "1. 添加目录节点""></a></h3><p>在系统菜单管理中添加一级目录(项目已内置「开发工具」目录,id=189,可直接复用):</p><table tabindex="0"><thead><tr><th>字段</th><th>值</th></tr></thead><tbody><tr><td>菜单名称</td><td>开发工具</td></tr><tr><td>菜单类型</td><td>目录(type=0)</td></tr><tr><td>路由地址</td><td>/tool</td></tr><tr><td>排序</td><td>50</td></tr></tbody></table><h3 id="_2-添加菜单节点-页面-" tabindex="-1">2. 添加菜单节点(页面) <a class="header-anchor" href="#_2-添加菜单节点-页面-" aria-label="Permalink to "2. 添加菜单节点(页面)""></a></h3><p>在目录下添加二级菜单(可导航页面,代码生成器创建的路径即为此格式):</p><table tabindex="0"><thead><tr><th>字段</th><th>值</th></tr></thead><tbody><tr><td>菜单名称</td><td>案例演示</td></tr><tr><td>菜单类型</td><td>菜单/页面(type=0)</td></tr><tr><td>路由地址</td><td>/tool/example</td></tr><tr><td>组件路径</td><td>tool/example/index</td></tr><tr><td>排序</td><td>1</td></tr></tbody></table><h3 id="_3-添加权限节点" tabindex="-1">3. 添加权限节点 <a class="header-anchor" href="#_3-添加权限节点" aria-label="Permalink to "3. 添加权限节点""></a></h3><p>在菜单下添加三级权限节点(type=1,<code>permission</code> 必填非空):</p><table tabindex="0"><thead><tr><th>字段</th><th>值</th><th>权限标识</th></tr></thead><tbody><tr><td>查看案例演示</td><td>type=1</td><td>sys:example:page</td></tr><tr><td>添加案例演示</td><td>type=1</td><td>sys:example:add</td></tr><tr><td>修改案例演示</td><td>type=1</td><td>sys:example:update</td></tr><tr><td>删除案例演示</td><td>type=1</td><td>sys:example:delete</td></tr><tr><td>导入案例演示</td><td>type=1</td><td>sys:example:import</td></tr><tr><td>导出案例演示</td><td>type=1</td><td>sys:example:export</td></tr></tbody></table><h3 id="_4-分配角色权限" tabindex="-1">4. 分配角色权限 <a class="header-anchor" href="#_4-分配角色权限" aria-label="Permalink to "4. 分配角色权限""></a></h3><p>在角色管理中,为角色勾选新增的权限节点(角色 → 菜单多对多,存于 <code>role_menu</code> 表)。</p><h2 id="菜单类型说明" tabindex="-1">菜单类型说明 <a class="header-anchor" href="#菜单类型说明" aria-label="Permalink to "菜单类型说明""></a></h2><table tabindex="0"><thead><tr><th>type</th><th>说明</th><th>前端行为</th></tr></thead><tbody><tr><td>0</td><td>菜单/目录(可导航)</td><td>目录渲染为侧边栏分组,页面渲染为菜单项(需填 <code>component</code>)</td></tr><tr><td>1</td><td>权限节点</td><td>不渲染,仅用于接口鉴权(<code>permission</code> 必填非空)</td></tr></tbody></table><h2 id="权限校验流程" tabindex="-1">权限校验流程 <a class="header-anchor" href="#权限校验流程" aria-label="Permalink to "权限校验流程""></a></h2><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span>1. 用户登录 → 获取用户角色(user_role 表)</span></span>
|
||
<span class="line"><span>2. 角色关联菜单 → 获取权限节点列表(role_menu 表,缓存于 Redis)</span></span>
|
||
<span class="line"><span>3. 请求接口 → auth.jwt 中间件读取控制器方法的 #[Permission] 注解(反射)</span></span>
|
||
<span class="line"><span>4. 检查权限码是否在用户权限列表中</span></span>
|
||
<span class="line"><span> ├─ 在 → 放行,进入 tenant / demo / log.operation 中间件</span></span>
|
||
<span class="line"><span> ├─ 不在 → 返回 {"code":403,"ok":false,"msg":"无访问权限"}</span></span>
|
||
<span class="line"><span> └─ 超级管理员(用户 ID=1)→ 跳过校验,直接放行</span></span>
|
||
<span class="line"><span>5. 菜单/角色菜单数据变更时,Observer 自动清除相关权限缓存</span></span></code></pre></div><div class="tip custom-block"><p class="custom-block-title">两级校验</p><ul><li><strong>后端</strong>:<code>#[Permission]</code> 注解 + <code>auth.jwt</code> 中间件(接口级,兜底);</li><li><strong>前端</strong>:<code>v-perm</code> 按钮指令(体验层,隐藏无权按钮)。</li></ul><p>前端隐藏不等于安全——后端注解校验才是权限的最终防线。详见 <a href="/zh/core/rbac.html">5.4 权限管理(RBAC)</a>。</p></div><h2 id="常见问题" tabindex="-1">常见问题 <a class="header-anchor" href="#常见问题" aria-label="Permalink to "常见问题""></a></h2><table tabindex="0"><thead><tr><th>现象</th><th>原因</th><th>处理</th></tr></thead><tbody><tr><td>超管正常、普通角色 403</td><td>角色未分配该权限节点</td><td>角色管理勾选对应菜单/按钮</td></tr><tr><td>改了权限不生效</td><td>权限缓存未失效</td><td>重新保存角色菜单(<code>RoleMenuObserver</code> 自动清除权限缓存),或重新登录</td></tr><tr><td>注解写了仍 403</td><td>权限码与菜单 <code>permission</code> 不一致</td><td>逐字符比对(注意大小写与冒号)</td></tr><tr><td>无 <code>#[Permission]</code> 的接口被拦截</td><td>接口放错位置</td><td>确认是否应为公开路由,移至中间件组外</td></tr></tbody></table>`,24)])])}const b=e(s,[["render",r]]);export{m as __pageData,b as default};
|