phplaravellaravel-sanctumsanctum

Laravel : How can I modify auth:sanctum middleware to return a 401 instead of redirect to login route?


Good evening,

I encounter a problem using Laravel and Sanctum to build an Api for a Mobile application.

I followed the documentation and define a route to get a token :

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
 
Route::post('/sanctum/token', function (Request $request) {
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
        'device_name' => 'required',
    ]);
 
    $user = User::where('email', $request->email)->first();
 
    if (! $user || ! Hash::check($request->password, $user->password)) {
        throw ValidationException::withMessages([
            'email' => ['The provided credentials are incorrect.'],
        ]);
    }
 
    return $user->createToken($request->device_name)->plainTextToken;
});

Tested it with postman, everything works fine, if I pass the right login and password, I'm able to get my token.

Now the problem I'm facing : I protected a route as the documentation said by using this middleware :

Route::middleware('auth:sanctum')->get(' ....' 

If I pass my token in headers, it works, but if I don't, Laravel tries to redirect me to /login route, which I don't want of course because I'm creating a mobile application. ** What I want is to receive a 401 if my token isn't valid. **

I tried to define a new middleware and copy the verification of the 'auth:sanctum' but I can't even find where this is defined, since it is not in the Kernel.php file.

I hope someone could explain me how I could find the code of 'auth:sanctum', so I can understand it and create a middleware with the comportement I need, but any help would be appreciate.

Thanks you in advance.


Solution

  • I have recently experienced the same issue.

    You are likely sending the Accept: application/json header with your request in Postman. This tells Laravel that the route is being access as an API route, rather than a web route and so returns a json response with 401.

    When you omit the header, the application assumes you are making a standard HTTP request from a web route. As you are not authenticated for web it simply redirects you back to the login route.

    If you are writing tests, you can use the getJson and postJson methods for the API routes.