使用Laravel和Passport在身份验证失败时使用状态代码401进行响应?

2022-08-30 22:39:02

我正在配置一个Laravel项目以使用Passport令牌身份验证。一切似乎都在工作,但是当中间件失败时,它会在响应正文中以状态和一堆HTML响应客户端。相反,我希望它以 状态 .auth:api200401

我在Laravel Passport的来源或文档中找不到任何关于做这样的事情。我甚至找不到中间件的源代码。

我的测试路线:

Route::get('/protected', function () {
    return response()->json([
        'success' => true
    ]);
})->middleware('auth:api');

配置/身份验证.php

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'appUsers',
    ],
],

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],

    'appUsers' => [
        'driver' => 'eloquent',
        'model' => App\Models\AppUser::class
    ],
],

答案 1

您可以通过将此标头与您的请求一起发送来解决。

Accept : application/json

这将发送此消息以及状态代码。401

{
    "message": "Unauthenticated."
}

答案 2

断续器

您需要确保请求包含标头。Accept: application/json

如果用户不进行身份验证,Laravel 将抛出 .AuthenticationException

此异常由 Illuminate/Foundation/Exceptions/Handler.php 中的方法处理,并依次调用在 app/Exceptions/Handler 中定义的方法.php:renderunauthenticated()

protected function unauthenticated($request, AuthenticationException $exception)
{
    if ($request->expectsJson()) {
        return response()->json(['error' => 'Unauthenticated.'], 401);
    }

    return redirect()->guest(route('login'));
}

如您所见,默认情况下,如果请求需要 JSON 响应,您将获得带有 JSON 错误正文的 401。如果请求不需要 JSON,则请求将重定向到登录页面。

如果您的请求具有标头或 .标头更适合 API 调用,而标头用于 ajax 调用。expectsJson()Accept: application/jsonX-Requested-With: XMLHttpRequestAccept: application/jsonX-Requested-With: XMLHttpRequest

因此,无需更改任何应用程序代码,只需确保请求包含标头即可。Accept: application/json

但是,如果需要在用户未通过身份验证时执行其他操作,则可以在 中修改此方法:unauthenticated()app/Exceptions/Handler.php

protected function unauthenticated($request, AuthenticationException $exception)
{
    if ($request->expectsJson()) {
        return response()->json(['error' => 'Unauthenticated.'], 401);
    }

    // return a plain 401 response even when not a json call
    return response('Unauthenticated.', 401);
}

推荐