ThinkPHP8 授权上下文传递需贯穿全链路:WebSocket 通过 token 锚定并写入 connection→auth;HTTP 请求在认证中间件用 withAttribute 挂载到 Request;多应用按域隔离 Auth 配置与实例;注解权限校验时从 Request 提取 auth 并结合元数据动态校验。

ThinkPHP8 中实现授权上下文传递,核心在于把用户身份、权限标识等关键信息,在连接建立、请求分发、中间件执行到控制器调用的全链路中稳定携带,不丢失、不污染、不越权。这不是加个 session 就完事,而是要结合连接生命周期与运行时上下文做精准注入。
TP8 与 Workerman 共存时透传身份
当 TP8 前端路由与 Workerman 长连接共用一套用户体系时,首次握手必须完成身份锚定:
- Web 端在建立 WebSocket 连接时,通过 URL 参数(如
?token=xxx)或首次onMessage消息体携带加密凭证 - Workerman 的
onConnect或onMessage中解析该凭证,调用 TP8 的 Auth 服务(如\think\facade\Auth::checkToken())验证并获取用户 ID、角色、权限码 - 将结果写入连接上下文:
$connection->auth = ['uid' => 1001, 'role' => 'admin', 'perms' => ['user:read', 'order:write']] - 后续所有消息处理都从
$connection->auth读取,不再重复鉴权
HTTP 请求中绑定授权上下文到 Request 对象
标准 HTTP 请求走 TP8 路由调度链,推荐在认证中间件中完成上下文挂载:
- 在
app/middleware/Authenticate.php的handle()方法里,验证 token 或 session 后,调用$request->withAttribute('auth', $userInfo) - 确保该中间件注册顺序靠前(早于权限中间件和控制器执行),这样后续所有中间件和控制器都能通过
$request->getAttribute('auth')安全读取 - 避免直接修改
$_SESSION或全局变量,防止并发覆盖或跨请求污染
多应用架构下隔离授权域
TP8 多应用模式天然支持上下文隔离,授权信息应按应用边界划分:
立即学习“PHP免费学习笔记(深入)”;
- 不同应用(如
admin/、api/、wechat/)使用独立的 Auth 配置项,例如config/admin/auth.php和config/api/auth.php - 在应用初始化阶段(如
app/admin/common.php),通过容器绑定当前应用专属的AuthInterface实现类 - 控制器中统一使用
\think\facade\Auth::user(),框架会根据当前 AppContext 自动解析对应实例,无需手动切换
注解权限校验时动态提取上下文
配合 @Permission 等自定义注解,权限中间件需主动拉取已挂载的授权上下文:
- 在权限中间件
CheckPermission的handle()中,先获取当前请求绑定的 auth 数据:$auth = $request->getAttribute('auth') - 再通过
$request->action()和$request->controller()定位方法,用AnnotationReader提取@Permission("user:delete")的 value - 最终调用
Auth::can($auth['uid'], $permissionCode),把上下文与注解元数据拼成完整校验逻辑



















