thinkphp rbac权限控制核心是三张表(auth_rule、auth_role、auth_role_rule)严丝合缝建模,中间件统一转换路由名为rule_name格式,登录后必须立即执行auth::setuser($uid)初始化缓存,并支持多角色权限并集查询与按role_id分片缓存。

ThinkPHP用MVC架构做权限控制,核心是把认证逻辑从控制器里抽出来,靠RBAC模型管住“谁能在哪干啥”。关键不在写多少代码,而在三张表怎么建、中间件怎么拦、缓存怎么刷——漏一个环节,权限就形同虚设。
三张表必须严丝合缝
auth_rule、auth_role、auth_role_rule 这三张表不是可选配置,是RBAC运行的物理基础。rule_name字段必须设为 UNIQUE 索引,不能留空;auth_role_rule 表必须用 role_id + rule_id 作联合主键,并分别加外键指向对应表。少一个约束,查权限时就会漏数据。初始插入超级管理员角色和基础节点(如 admin.user.list、admin.menu.delete)时,type 字段要明确标为 action 或 menu,否则菜单渲染和接口拦截会错判。
中间件得懂路由名怎么转权限标识
PermissionCheck 中间件不是简单调 Auth::check() 就完事。它得先拿到当前请求的真实路由名,再标准化成 rule_name 格式:用 request()->rule()->getName() 获取原始值(比如 admin/user/edit),然后 str_replace('/', '.', $name) 转成 admin.user.edit。如果用了资源路由或闭包定义,就得 fallback 到拼接 controller 和 action,比如 'admin.' . Str::snake($request->controller()) . '.' . $request->action()。不统一这一步,权限校验永远对不上号。
登录后必须立刻生成权限缓存
用户登录成功那一瞬间,控制器里必须紧跟着执行 Auth::setUser($uid),且必须在重定向之前。这步不是可有可无的初始化,而是把该用户所有角色对应的 rule_name 数组一次性塞进 session(key 是 think_auth)。没这步,后续所有中间件里的 check 都查不到数据,一律放行或一律拦截——表面看着正常,实际权限已失效。你可以清空 session 后重新登录,检查 session 中是否出现 think_auth 键,值里要有 role_id 和 rules 数组。
多角色权限得合并查,不能只认一个
一个用户可能同时属于管理员和编辑两个角色,权限不是取交集,而是并集。校验时不能只查第一个角色,必须遍历 auth_group_access 得到全部 role_id,再逐个查 auth_role_rule 拿 rule_id,最后联查 auth_rule 得到完整 rule_name 列表。Redis 缓存 key 要按 role_id 分开存(如 auth_rules_by_role_1),查的时候用 SMEMBERS 批量取,避免高并发下直连数据库被拖垮。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











