thinkphp8动态授权需菜单表含permission_code字段并统一风格,服务层过滤组装权限菜单树、缓存可控,中间件确保auth上下文就绪,前端仅安全渲染已过滤菜单。

ThinkPHP8 添加菜单动态授权,核心不是“加个菜单再配权限”,而是让菜单数据本身携带可校验的权限标识,并在服务层完成过滤与组装。整个过程必须后端驱动、缓存可控、结构可溯。
菜单表必须带 permission_code 字段
不要只存 name、url、pid。每条菜单记录需明确绑定一个权限码,比如:
•「用户管理」→ admin.user.list
•「新增用户」→ admin.user.create
•「编辑用户」→ admin.user.edit
这个字段要和路由规则名、AuthRule 表中的 name 字段完全一致(斜杠或点号风格需统一),否则 Auth::check() 会始终返回 false。
后端服务层生成已授权菜单树
禁止在模板里用 {if $auth->check('')} 包裹菜单项。正确做法是:在控制器或 MenuService 中调用封装好的方法,例如:
- 查询当前用户所有角色关联的权限码集合(从 auth_rule + auth_group_access 表中获取)
- 查出全部菜单,按 permission_code 筛出用户有权限的节点
- 基于 path 字段(如 "0-1-5-12")重建层级关系,递归组装成完整树
- 结果缓存,key 建议为 menu_user_{$uid}_{$roleHash},避免重复查询
中间件确保权限上下文就绪
菜单能动态授权的前提是 Auth 组件已加载当前用户权限。常见失效原因:
- 登录成功后没调 Auth::setUser($uid),导致后续 check() 查不到缓存
- 用了多应用(如 admin/api),但 check() 没传 app 名,应写成 Auth::check('admin.user.list', $uid, 'admin')
- 菜单渲染前未触发权限刷新,角色变更后仍显示旧菜单——需在角色/权限修改后主动清除 cache('auth_rule_*') 和 cache('menu_user_*')
前端只负责安全渲染,不参与判断
视图中接收的是已过滤完毕的菜单数组,直接递归渲染即可:
- 使用独立模板片段(如 menu_tree.html),限制最大深度({if $depth lt 4})防爆栈
- 每个菜单的 url 必须由 url() 函数生成,不拼接字符串
- 不调用任何 Auth 方法,不暴露 permission_code 到前端 JS
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











