phplaravelpostmanlaravel-sanctum

Laravel 10 Token authentication with Sanctum returns "401 Unauthorized"


I'm building a Laravel API with Sanctum authentication and testing it with Postman but all I can get is a 401 Unauthorized response. The project is a clear Laravel 10 project with Sanctum. I've installed it, migrated it's tables and executed the default DatabaseSeeder.

As I want to this API to work as a back-end for multiple front-end in different applications, I want to work with Sanctum Tokens(Is there a better option?). I've copied the token creation route from this doc(just changed device_name property name to token_name, didn't touched anything more) into routes/api.php:

Route::post('/sanctum/token', function (Request $request) {
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
        'token_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->token_name)->plainTextToken;
});

I've changed the following points event though I don't know if it's needed as Laravel docs don't mention them(found these on web searches):

This is my Postman request:

enter image description here

I'm not sure how to overcome this problem. I don't want to start any front-end app without making sure API routes works.


Solution

  • In your Postman request, you are targeting a web route /sanctum/token , while you implemented the authentication route in your api routes that should be /api/sanctum/token

    It's weird that you are getting a 401 response, when you should have gotten a 404 response.

    Other than that, I don't see any problem with your implementation, once you use the /api/sanctum/token in your postman request with correct headers (Accept, Content-Type) you should get the proper response based on your route configuration; either invalid credentials or a plain text token which you can then store somewhere and add it on Authorization header for sub-sequent request.

    So, first issue a plain text token via user authentication

    POST https://mydomain.me/api/sanctum/token HTTP/1.1
    Accept: application/json
    Content-Type: application/json
    
    {
        "email": "test@me.com",
        "password": "something-password",
        "token_name": "test"
    }
    

    Once successful, save the plaintext token, then use it on sub-sequent request protected by auth sanctum middleware e.i. you have this api route

    Route::group(['middleware' => 'auth:sanctum'], function () {
        Route::get('/whatever-routes-protected-by-auth-sanctum', [MyDuhController::class, 'duh'])->name('duh');
    });
    

    then your request

    GET https://mydomain.me/api/whatever-routes-protected-by-auth-sanctum HTTP/1.1
    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer PLAIN_TEXT_TOKEN
    
    {
        "hey": "Yes",
        "hi": "hello"
    }
    

    In summary, always append /api in your base URL if you are targetting an API route