ThinkPHP6中实现授权事件监听需通过全局中间件捕获401/403响应、自定义Guard触发内部事件或路由中间件细粒度审计,而非依赖未定义的auth_failed等钩子。

ThinkPHP6 中添加授权事件监听,关键不是注册一个“授权成功/失败”的钩子,而是利用框架已有的事件机制,在权限校验的关键节点注入自定义逻辑。Auth 本身不内置标准事件,但你可以通过中间件、自定义 Guard 或响应拦截等方式实现等效监听效果。
在全局中间件中监听未授权响应
这是最可靠、覆盖最全的方式,能捕获所有 401/403 响应,包括 Auth::check() 失败、JWT 过期、白名单绕过等场景:
- 新建中间件(如 app/middleware/AuthFailLogger.php)
- 在
handle()方法中调用$next($request)后检查响应码:if (in_array($response->getCode(), [401, 403])) - 提取必要信息:URL、IP、脱敏后的
Authorization头(取前10位+***)、请求方法、参数($request->param()) - 写入日志或数据库表(如 auth_fail_log),字段建议含
url、method、ip、auth_header_snippet、param_json、created_at
通过自定义 Auth Guard 触发内部事件
如果你使用了自定义认证驱动(如继承 thinkuthGuard),可在其 check() 或 authenticate() 方法中手动触发事件:
- 在 Guard 类中引入
thinkEvent - 校验失败时调用
Event::trigger('auth.fail', [$user, $reason]) - 在 app/event.php 中注册监听器,例如:
['auth.fail' => ['app\listener\AuthFailListener']] - 注意:该方式仅覆盖你这个 Guard 的校验路径,无法捕获中间件提前返回或 Token 解析异常等情况
避免依赖不可靠的钩子名
不要直接监听 auth_failed 或 auth_fail 等未注册的钩子:
立即学习“PHP免费学习笔记(深入)”;
- ThinkPHP6 核心未默认定义这些事件,监听会静默失效
- 若使用第三方 Auth 扩展,需查阅其文档确认是否暴露了对应事件
- 自行注册钩子需确保行为类存在且命名准确,否则调试困难
结合路由中间件做细粒度权限审计
对特定接口或模块做授权行为记录,可在路由定义时绑定中间件:
- 在 route/app.php 中为敏感路由添加中间件:
->middleware(['auth', 'log_auth_action']) - 新建 LogAuthAction 中间件,在
handle()开头读取用户身份($this->auth->id()),结尾记录访问动作与结果 - 适用于需要追踪“谁在何时访问了哪个资源”,而不仅是失败事件



















