Laravel Passport OAuthServerException无法冒泡至Handler.php,求处理过期Token返回JSON方案
问题场景
使用Laravel Passport的Authorization Code Grant(授权码授权模式)做用户认证,希望访问受auth:api中间件保护的路由时,若访问令牌过期能返回自定义JSON响应,但目前仅能在Handler.php的report方法中捕获League\OAuth2\Server\Exception\OAuthServerException,无法捕获官方文档要求的Laravel\Passport\Exceptions\OAuthServerException。
Passport官方升级文档相关内容(翻译)
OAuth错误的可渲染异常
Laravel Passport 11.x及以上版本,会将League OAuth2服务器抛出的异常转换为Laravel\Passport\Exceptions\OAuthServerException实例,该异常实现了Laravel的Renderable接口,允许你在应用的异常处理器中自定义响应格式。
在此之前,开发者可能需要捕获League的异常类;现在需更新异常处理器,改为捕获Laravel Passport提供的异常类。
解决步骤
1. 确认Passport版本
确保你的Laravel Passport版本为11.x及以上,可通过查看composer.json中的laravel/passport版本号确认。
2. 修改异常处理器Handler.php
在app/Exceptions/Handler.php中注册针对Laravel\Passport\Exceptions\OAuthServerException的渲染逻辑。以Laravel 8+版本为例,推荐使用register方法中的renderable闭包:
<?php namespace App\Exceptions; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Laravel\Passport\Exceptions\OAuthServerException; class Handler extends ExceptionHandler { // ... 其他代码 public function register() { // 处理Passport OAuth异常,返回JSON响应 $this->renderable(function (OAuthServerException $e, $request) { // 判断是否为API请求 if ($request->expectsJson() || $request->is('api/*')) { return response()->json([ 'code' => $e->getStatusCode(), 'message' => $e->getMessage(), 'error' => $e->errorType() // 获取具体错误类型,比如token_expired ], $e->getStatusCode()); } }); } }
3. 检查配置与缓存
- 确认
config/auth.php中API守卫使用Passport驱动:'guards' => [ 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ], - 清除应用缓存,确保配置生效:
php artisan cache:clear php artisan config:clear
4. 测试验证
使用过期的访问令牌请求受auth:api保护的API路由,验证是否返回你自定义的JSON响应。
内容的提问来源于stack exchange,提问作者swh

