使用 Laravel 和 Passport 在身份验证失败时响应状态码 401?
Posted
技术标签:
【中文标题】使用 Laravel 和 Passport 在身份验证失败时响应状态码 401?【英文标题】:Respond with status code 401 on authentication failure using Laravel and Passport? 【发布时间】:2017-07-28 04:27:06 【问题描述】:我正在配置一个 Laravel 项目以使用 Passport 令牌身份验证。一切似乎都在工作,但是当auth:api
中间件失败时,它会以200
的状态和响应正文中的一堆html 响应客户端。相反,我希望它以401
的状态响应。
我在 Laravel Passport 源代码或文档中找不到有关执行此类操作的任何内容。我什至找不到中间件的来源。
我的测试路线:
Route::get('/protected', function ()
return response()->json([
'success' => true
]);
)->middleware('auth:api');
配置/auth.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】:在中间件中你可以这样返回:
return abort(401);
【讨论】:
我没有写中间件。我正在尝试使用 Larave/Passport 提供的中间件(auth:api
)。
不想改源码的可以扩展中间件。
auth
中间件仅包含 1 个方法。难道我不必只覆盖该方法并完全重写它吗?
您的新中间件应该扩展 Illuminate\Auth\Middleware\Authenticate。【参考方案2】:
如果用户没有进行身份验证,Laravel 会抛出一个AuthenticationException
。
此异常由Illuminate/Foundation/Exceptions/Handler.php
中的render
方法处理,并依次调用您的app/Exceptions/Handler.php
中定义的unauthenticated()
方法:
protected function unauthenticated($request, AuthenticationException $exception)
if ($request->expectsJson())
return response()->json(['error' => 'Unauthenticated.'], 401);
return redirect()->guest(route('login'));
如您所见,默认情况下,如果请求需要 JSON 响应,您将收到带有 JSON 错误正文的 401。如果请求不期望 JSON,则将请求重定向到登录页面。
如果您的请求具有Accept: application/json
标头或X-Requested-With: XMLHttpRequest
,则expectsJson()
方法将返回true。 Accept: application/json
标头更适合 api 调用,而 X-Requested-With: XMLHttpRequest
标头用于 ajax 调用。
因此,无需更改任何应用程序代码,只需确保请求包含 Accept: application/json
标头即可。
但是,如果您需要在用户未通过身份验证时执行不同的操作,您可以在app/Exceptions/Handler.php
中修改此unauthenticated()
方法:
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);
【讨论】:
上帝保佑你兄弟 如果您正在使用Laravel 5.5
并且这些都不起作用,并且如果您记得删除所有类型的缓存,请尝试在您的所有服务器中运行php artisan config:cache
。一起被困了几个小时,只有这样才能使它起作用。希望它可以帮助别人!【参考方案3】:
您可以通过在请求中发送此标头来解决它。
Accept : application/json
这将发送带有401
状态码的消息。
"message": "Unauthenticated."
【讨论】:
我想向这个 JSON 响应添加自定义代码,例如 ( "error" : 401 "message": "Unauthenticated." )。我该怎么做? 我不明白这个答案,您能否补充一下,告诉我们如何发送该标头? @Gjaa 您可以查看此答案以了解如何在 Laravel 响应中添加标头 ***.com/questions/17548569/… 如果您正在使用Laravel 5.5
并且这些都不起作用,并且如果您记得删除所有类型的缓存,请尝试在您的所有服务器中运行php artisan config:cache
。一起坚持了几个小时,只有这样才能使它起作用。希望它可以帮助别人!以上是关于使用 Laravel 和 Passport 在身份验证失败时响应状态码 401?的主要内容,如果未能解决你的问题,请参考以下文章
使用 VueX 和 Laravel Passport 进行身份验证
Laravel 5.3 + Passport:总是未经身份验证的错误
Laravel Passport API:检索经过身份验证的令牌