Files
2026-10-25 18:52:36 +08:00

9 lines
8.6 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
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 &quot;3.8 权限节点配置&quot;">​</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 &quot;Example 模块权限码&quot;">​</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(&#39;sys:example:page&#39;, &#39;示例分页&#39;)]</code>)必须与菜单管理中配置的 <code>permission</code> 字段<strong>完全一致</strong>,否则鉴权不通过。</p></div><h2 id="配置步骤" tabindex="-1">配置步骤 <a class="header-anchor" href="#配置步骤" aria-label="Permalink to &quot;配置步骤&quot;">​</a></h2><h3 id="_1-添加目录节点" tabindex="-1">1. 添加目录节点 <a class="header-anchor" href="#_1-添加目录节点" aria-label="Permalink to &quot;1. 添加目录节点&quot;">​</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 &quot;2. 添加菜单节点(页面)&quot;">​</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 &quot;3. 添加权限节点&quot;">​</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 &quot;4. 分配角色权限&quot;">​</a></h3><p>在角色管理中,为角色勾选新增的权限节点(角色 → 菜单多对多,存于 <code>role_menu</code> 表)。</p><h2 id="菜单类型说明" tabindex="-1">菜单类型说明 <a class="header-anchor" href="#菜单类型说明" aria-label="Permalink to &quot;菜单类型说明&quot;">​</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 &quot;权限校验流程&quot;">​</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> ├─ 不在 → 返回 {&quot;code&quot;:403,&quot;ok&quot;:false,&quot;msg&quot;:&quot;无访问权限&quot;}</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 &quot;常见问题&quot;">​</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};