ThinkPHP6需手动集成授权机制,推荐用中间件统一校验权限:提取路由名与用户权限白名单比对,失败返回403;权限数据须经数据库四表关联设计并缓存,前端控制须以后端白名单为准,接口层必须二次校验。

ThinkPHP6 不提供开箱即用的控制器授权机制,授权必须手动集成到请求生命周期中。核心不是“给控制器加授权”,而是通过中间件或基类控制器,在进入具体方法前完成权限校验。
用中间件统一拦截校验
这是推荐方式,避免在每个控制器里重复写判断逻辑。
- 创建中间件如 app/middleware/AuthMiddleware.php,在
handle()方法中获取当前用户角色关联的所有权限name(例如'user:edit'、'order:export') - 从请求中提取路由标识:优先用
$this->request->rule()->getName()或自定义路由别名,不依赖$this->request->action()(易与真实方法名错位) - 检查该路由名是否在用户权限白名单中,例如:
in_array('admin:user:index', $permissionList) - 未通过时直接返回 JSON 错误或重定向至 403 页面;通过则调用
$next($request) - 在
app/middleware.php中注册为全局中间件,或按路由分组绑定(如所有admin/下路由)
在基础控制器中封装校验
适合后台管理类项目,对页面级访问控制更直观。
- 继承
app\BaseController,在initialize()中调用权限检查方法 - 校验依据是当前用户已激活角色所拥有的全部权限
name,不是查用户表字段或硬编码规则 - 权限列表建议缓存:
Cache::get('permission_list_' . $uid),并在角色变更、权限更新、用户登出时清除 - 失败时可跳转:
$this->redirect('/admin/403'),或输出模板提示
权限数据结构要支撑校验逻辑
数据库设计直接影响校验是否可靠、扩展是否灵活。
立即学习“PHP免费学习笔记(深入)”;
- 必须有四张表:用户(
sys_user)、角色(sys_role)、权限(sys_permission)、关联(sys_role_permission和sys_user_role) -
sys_permission表需含name(英文冒号分隔,如'article:publish')、type('menu'或'api')、path(对应路由或接口地址) - 菜单显隐、按钮灰显等前端控制,必须以后端返回的
permission_name白名单为准,不能仅靠前端 JS 判断 - 接口层必须二次校验——前端隐藏了按钮,不代表后端可跳过权限检查
不要依赖 think\Auth 类
框架自带的 Auth 类默认走配置文件或静态数组,不支持动态权限变更实时生效。
- 若要用,必须继承重写
\think\Auth,覆盖_getAccessList()方法,使其查数据库并配合缓存管理 - 登录、角色分配、权限修改后,务必主动清理缓存:
Cache::delete('auth_' . $uid) - 更稳妥的做法是绕过 Auth 类,直接基于模型查询 + 缓存封装自己的
AuthService



















