Skip to content

🛡️ 权限与菜单

SunAdmin 后台权限由“管理员 - 角色 - 菜单/权限标识”组成,前端动态路由也依赖后端菜单返回。

🎯 本页目标

读完本章节后,应能掌握:

  • 后台与用户端的认证中间件分别要求什么模型、注入哪些属性。
  • 何时使用普通 Get/PostOpenGet/OpenPostapi.try-auth
  • 菜单数据如何与前端 src/views.vue 文件对应。
  • 新增页面或按钮时应同步维护哪些菜单与权限数据。

🪛 核心目录

能力后端路径前端路径
动态路由MenuController@routefrontend/admin/src/router/index.ts
当前用户信息AdminController@mySelffrontend/admin/src/stores/modules/user.ts

🔐 后台认证

后台接口默认挂载 admin.auth,中间件:

text
app/Core/Http/Middleware/AdminAuthMiddleware.php

中间件要求 Sanctum 当前用户是:

php
Modules\System\Domain\Models\Auth\Admin

认证通过后会写入:

php
$request->attributes->set('admin_id', $user->getKey());
$request->attributes->set('admin', $user);

控制器内可使用:

php
$this->adminId();
$this->admin();

👤 用户端认证

用户端 Api 目录默认挂载 api.site + api.auth,普通 Get/Post 接口默认需要用户登录。登录校验中间件:

text
app/Core/Http/Middleware/ApiAuthMiddleware.php

认证通过后写入:

php
$request->attributes->set('user_id', $user->getKey());
$request->attributes->set('user', $user);

控制器内可使用:

php
$this->userId();
$this->user();

🪪 尝试登录

api.try-auth 适合在公开接口里做个性化逻辑。接口本身应使用 OpenGet / OpenPost 排除强制登录;游客可访问,携带有效 token 时可读取用户身份。

中间件类:

text
app/Core/Http/Middleware/ApiTryAuthMiddleware.php

典型场景:

  • 首页推荐。
  • 文章列表。
  • 上传临时文件。
  • AI 推荐。

注意:涉及用户资料、地址、订单、账户资金等强身份数据时使用普通 Get/Post 即可,因为 Api 目录默认已经要求登录,不需要重复标注 api.auth

🧭 菜单与动态路由

Admin 端动态路由来自后端菜单树。菜单中的 component 字段使用相对 src/views 的页面路径,前端启动时会扫描 src/views/**/*.vue 并按 component 加载对应组件。

在后台菜单管理页面可以直接选择 component,无需手工录入。

权限菜单示意图

菜单类型:

类型前端行为
目录渲染为 Layout 或 RouterView
菜单加载真实页面组件
按钮/权限不生成页面,用于操作权限判断

🏷️ 权限标识

权限标识通常放在菜单数据的 perms 字段。前端 user store 保存:

ts
perms: string[]

用法示例:

vue
<el-button v-perm="['article.add']">新增</el-button>

页面应通过权限标识控制按钮显示,例如新增、编辑、删除、审核、导出等。

➕ 新增权限流程

  1. 后端新增接口,并确定是默认登录接口还是 OpenGet / OpenPost 公开接口。
  2. Admin 新增页面或按钮。
  3. 在菜单初始数据中新增菜单记录或按钮权限记录。
  4. componentSystem/user/index 这类相对 src/views 的路径。
  5. perms 使用稳定、可读、可搜索的权限标识。
  6. 登录后台后刷新权限,确认 refreshUserAccess() 能拿到新菜单。

❓ 常见问题

问题原因处理
登录后 403当前角色没有有效菜单检查角色菜单授权
菜单点击组件缺失component 与前端路径不匹配对照 src/views 修正
按钮不显示权限标识未返回或页面判断错误检查 perms
新菜单本地有、部署没有只改了数据库未改 Seeder同步初始数据