Laravel API未授权时如何取消跳转登录并返回JSON响应
解决Laravel API未授权时返回JSON而非跳转的问题
当你的Laravel API接口(比如UserController@profile)在无token调用时抛出Route [login] not defined错误,本质是Laravel默认的未授权处理逻辑会尝试跳转到登录页面,但API项目没有配置对应的登录路由和模板。要让它返回JSON响应,可通过以下几种方式处理:
方案一:重写异常处理类的未授权方法
修改app/Exceptions/Handler.php文件,重写unauthenticated方法,判断请求是否为API类型,返回JSON格式的401响应:
<?php namespace App\Exceptions; use Illuminate\Auth\AuthenticationException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Http\Request; use Throwable; class Handler extends ExceptionHandler { // ... 保留原有代码 /** * 处理未授权的认证异常 */ protected function unauthenticated($request, AuthenticationException $exception) { // 判断请求是否期望JSON响应(API请求通常会携带Accept: application/json头) if ($request->expectsJson()) { return response()->json([ 'code' => 401, 'message' => '未授权,请提供有效的认证令牌', 'error' => $exception->getMessage() ], 401); } // 非API请求仍走原跳转逻辑(按需保留) return redirect()->guest($exception->redirectTo() ?? route('login')); } }
方案二:确保API路由使用正确的认证中间件
在routes/api.php中,确保接口路由绑定auth:api中间件(对应config/auth.php中配置的api guard):
use App\Http\Controllers\UserController; Route::middleware('auth:api')->group(function () { Route::get('/user/profile', [UserController::class, 'profile']); });
同时检查config/auth.php的guards配置,确保api guard的驱动匹配你的认证方案(比如sanctum、token或passport):
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'sanctum', // 按需替换为token/passport 'provider' => 'users', 'hash' => false, ], ],
方案三:自定义认证中间件(可选)
如果需要更灵活的处理逻辑,可以自定义中间件替换默认的auth:api:
- 创建中间件:
php artisan make:middleware ApiAuthenticate
- 在
app/Http/Middleware/ApiAuthenticate.php中编写逻辑:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class ApiAuthenticate { public function handle(Request $request, Closure $next) { if (!Auth::guard('api')->check()) { return response()->json([ 'code' => 401, 'message' => '未授权,请提供有效的认证令牌' ], 401); } return $next($request); } }
- 在
app/Http/Kernel.php注册中间件:
protected $routeMiddleware = [ // ... 其他中间件 'api.auth' => \App\Http\Middleware\ApiAuthenticate::class, ];
- 在路由中使用自定义中间件:
Route::middleware('api.auth')->get('/user/profile', [UserController::class, 'profile']);
内容的提问来源于stack exchange,提问作者Maher
相关产品推荐
相关产品推荐

