ThinkPHP 8通过路由分组绑定授权中间件实现网关层能力:第一步定义/api路由分组并挂载api.auth中间件;第二步在中间件中先解析用户身份、调用Auth::setUser($uid)激活上下文,再执行Auth::check()校验权限;第三步确保auth_rule表中name字段与完整路由标识严格一致(如api/user/:id),多应用需传入应用名参数。

ThinkPHP 8 本身不内置“网关层”概念,但可通过路由分组 + 中间件链 + 权限服务集成,在应用入口处模拟 API 网关的核心能力:统一鉴权、路由拦截、多策略校验。关键不是加一个叫“网关”的模块,而是把授权逻辑前置到请求最开始可干预的位置。
网关层授权的本质是“路由级前置拦截”
TP8 的请求流程是:接收请求 → 匹配路由 → 执行中间件 → 调用控制器。所谓“网关层”,就是让授权中间件在路由匹配后、控制器执行前,对所有目标路由(如 /api/**)做统一检查。它不依赖独立进程或反向代理,而是在框架内完成轻量网关职责。
- 必须绑定在路由分组上,不能只靠全局中间件
- 需区分「认证」(你是谁)和「授权」(你能做什么),两者顺序不能颠倒
- 授权判断必须基于当前用户上下文,且缓存权限数据避免重复查库
正确配置网关级授权的三步实操
-
第一步:定义受控路由分组,显式挂载授权中间件
在route/app.php中集中管理 API 入口:use think\facade\Route; Route::group('api', function () { Route::get('user/:id', 'api.UserController@info'); Route::post('order', 'api.OrderController@create'); })->middleware('api.auth'); // 注意:这里绑定的是中间件别名 -
第二步:注册并实现
api.auth中间件,完成双阶段校验
在app/middleware/ApiAuthMiddleware.php中:- 先调用 JWT 或 Session 解析出
$uid,失败则直接返回 401 - 再调用
Auth::setUser($uid)激活权限缓存(否则Auth::check()始终为 false) - 最后根据当前路由名(如
api/user/1)调用Auth::check()判断是否允许访问
⚠️ 常见错误:漏掉
Auth::setUser($uid);或把Auth::check()放在setUser之前。 - 先调用 JWT 或 Session 解析出
-
第三步:确保权限规则与路由名严格对齐
auth_rule表中的name字段必须等于完整路由标识,例如:立即学习“PHP免费学习笔记(深入)”;
- 路由
Route::get('api/user/:id', ...)→ 规则name = 'api/user/:id' - 不支持通配符(如
api/*),也不接受点号写法(api.user.index是错的) - 多应用下需传入应用名参数:
Auth::check('user/delete', $uid, 'api')
- 路由
如需支持按钮级或字段级细粒度控制
- 按钮显隐:在模板中用
{:Auth::check('user.edit')}控制 DOM 渲染 - 接口字段过滤:在控制器中手动调用
Auth::check('user.phone')决定是否返回手机号字段 - 动态策略(进阶):接入 PHP-Casbin,将策略存入数据库,
p, admin, /api/users, GET, allow类规则修改后立即生效,无需重启
授权不是加个中间件就完事,核心在于:路由命名即权限标识、用户上下文必须激活、检查时机必须在控制器之前。做到这三点,TP8 就具备了生产可用的网关层授权能力。



















