ThinkPHP 8 不支持“路由元数据授权”机制,权限控制需通过路由中间件实现:可利用命名路由的 option() 存储权限标识(如 'system:mail:edit'),或在中间件中解析路由名、控制器/方法名进行校验。

ThinkPHP 8 不提供名为“路由元数据授权”的内置机制。框架本身没有将权限控制逻辑直接嵌入路由定义元数据(如注解属性或 route.php 配置项)的设计。所谓“路由元数据授权”,实际是开发者对权限校验环节的一种误称或混淆,本质仍是中间件 + 路由分组 + 控制器/方法标识的组合实现。
核心思路:用中间件拦截路由,结合路由标识或控制器信息做权限判断
TP8 的权限控制必须落在请求生命周期中可干预的位置,最合理、最常用的是路由中间件。你不能在 #[Route] 或 Route::get() 里直接写“auth_level=3”这类元数据并指望框架自动鉴权——它不会识别,也不会执行。
- 给关键路由组统一加权限中间件:
Route::group('admin', function () {
Route::get('users', 'admin/User@index');
Route::post('roles', 'admin/Role@save');
})->middleware('check_permission'); - 中间件内根据当前匹配到的路由名、控制器类、方法名或自定义路由参数做判断:
在 app/middleware/CheckPermission.php 的 handle() 方法中,可用:$route = $request->route();<br>if ($route && method_exists($route, 'getName')) {<br> $name = $route->getName(); // 比如 'admin.users.index'<br> // 查权限表或配置,判断当前用户是否有该 name 的权限<br>} - 也可利用路由地址字符串反向解析:
$action = $route->getActionName(); // 返回 'admin/User@index'<br>list($app, $controller, $method) = explode('/', str_replace('.', '/', $action));<br>// 然后查 admin_user_read 权限是否开通
若想“伪元数据化”,可用命名路由 + 自定义属性
虽不能原生支持授权字段,但可通过命名路由(name)承载权限标识,并在中间件中约定解析规则:
- 定义路由时显式绑定权限标识:
Route::get('setting/mail', 'admin/Setting@mail')->name('setting.mail')->option(['permission' => 'system:mail:edit']); - 中间件中读取 option:
$permission = $route->getOption('permission');<br>if ($permission && !Auth::hasPermission($permission)) {<br> throw new HttpException(403, '无访问权限');<br>} - 注意:option() 是 TP8 支持的路由扩展属性,不会影响匹配,仅作存储用途,需自行在中间件中提取使用。
注解路由场景下如何“带权限信息”
#[Route] 属性本身不支持自定义字段,但你可以:
立即学习“PHP免费学习笔记(深入)”;
- 用 #[Middleware] 显式附加中间件:
#[Route('api/user/:id', method: 'GET')]
#[Middleware('auth', 'check_api_scope')]
public function info($id) { ... } - 或在注解中用约定格式写注释说明(仅作文档,不参与运行):
#[Route('admin/log', method: 'GET')] // @permission admin:log:list - 更可靠的做法:把权限标识写进控制器方法的 PHPDoc,再通过反射在中间件中读取(需自行开发解析逻辑,非框架默认能力)。
不要踩的坑
- 别在 #[Get] 或 #[Post] 注解里硬塞 middleware 参数——会被完全忽略,无提示;
- 别依赖路由表达式(如 'admin/*')做权限通配——表达式是匹配用的,不是权限策略;
- 别把权限判断逻辑写在控制器里再跳转——违背前置拦截原则,已进入业务层,存在安全盲区;
- 别用 config/route.php 的全局变量存权限映射——无法按请求动态校验用户角色。



















