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):
config/cors.php (changed default value false
to true
):
'supports_credentials' => true,
Http/Kernel.php (uncommented following line):
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
This is my Postman request:
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.
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