thinkphp 8 的权限注解(如@auth、@permission)仅为标记,需配合中间件实现校验:@auth适配内置rbac,执行php think rbac:install初始化表并启用authmiddleware;@permission需自定义中间件解析注解值并调用权限服务;路由级权限可结合#[route]的option参数统一管理;注意注解路径、中间件执行顺序及jwt场景下权限来源。

ThinkPHP 8 本身不直接解析权限注解,@Permission 或 @auth 这类注解只是“标记”,真正起作用的是你写的中间件——框架只负责把注解信息传过去,校验逻辑必须你自己写。
用 @auth 注解 + 内置 RBAC 模块(推荐新手)
这是最省事的开箱方案,适合快速上线基础权限控制:
- 先执行命令初始化数据库表:
php think rbac:install,生成 user、role、permission 等五张表 - 在控制器方法上加注解,例如:
/** @auth('user.delete') */<br>public function delete() { ... } - 确保已启用
AuthMiddleware(通常在app/middleware.php中全局或路由组绑定) - 注意:按钮级显隐需在模板里手动判断,比如
{if Auth::check('user.edit')}编辑按钮{/if}
用 @Permission 注解 + 自定义中间件(推荐进阶)
灵活性更高,适合需要统一管理权限码、对接 JWT 或做字段级控制的场景:
- 安装扩展:
composer require topthink/think-annotation - 自定义注解类,继承
think\annotation\Annotation,例如Permission类对应@Permission("order:pay") - 在权限中间件(如
CheckPermission)的handle()方法中:
– 用$request->controller()和$request->action()拼出完整方法名
– 调用AnnotationReader::getClassMethodAnnotations()提取该方法的@Permission实例
– 取出$annotation->value,传给你的权限服务(如Auth::check($code)) - 确保该中间件在认证中间件之后执行,否则
Auth::user()可能为空
注解路由绑定权限(配合 @Route 使用)
如果希望权限控制和路由定义更紧密,可把权限码作为路由元数据绑定:
- 使用
#[Route]属性(PHP 8 语法),例如:#[Route('admin/user/:id', method: 'DELETE', option: ['permission' => 'user:delete'])] - 在权限中间件中,通过
$request->rule()->getOption('permission')获取权限码 - 这种方式避免了重复写注解,也方便统一做路由维度的权限审计
- 注意:
#[Get]或#[Post]不支持option,必须用#[Route]
关键提醒:别踩这些坑
很多问题其实不是注解没生效,而是环境或逻辑没对齐:
-
#[Route]必须配合AnnotationRoute::init()初始化,且config/annotation.php中'route' => ['enable' => true] - 控制器类必须在
app/controller/下(或多应用对应路径),方法必须是public - 权限中间件不能依赖
Auth::check()做 API 校验——它默认走 Session;JWT 场景应从 token payload 读取权限数组 - 权限缓存建议按角色 ID 切分(如
role_permissions_5),变更时同步清理,避免脏数据
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











