Respond with status code 401 on authentication failure using Laravel and Passport?
You can solve it by sending this header with your request.
Accept : application/json
This will send this message with 401
status code.
{
"message": "Unauthenticated."
}
If a user does not authenticate, Laravel will throw an AuthenticationException
.
This exception is handled by the render
method in Illuminate/Foundation/Exceptions/Handler.php
, and will in turn call the the unauthenticated()
method which is defined in your app/Exceptions/Handler.php
:
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest(route('login'));
}
As you can see, by default, if the request expects a JSON response, you'll get a 401 with a JSON error body. If the request does not expect JSON, the request is redirected to the login page.
The expectsJson()
method will return true if your request has either the Accept: application/json
header, or the X-Requested-With: XMLHttpRequest
. The Accept: application/json
header is more appropriate for api calls, whereas the X-Requested-With: XMLHttpRequest
header is used for ajax calls.
So, without changing any of your application code, just make sure the requests include the Accept: application/json
header.
However, if you need to have a different action happen when a user is not authenticated, you can modify this unauthenticated()
method in 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);
}
In middleware you can return like this:
return abort(401);