Authenticating with API Tokens Using Laravel Sanctum
web-application-framework laravel
Let’s try API token authentication using Laravel Sanctum.
References
What is Laravel Sanctum?
Laravel Sanctum is an authentication system used for SPAs (single page applications), mobile applications, and simple token-based APIs.
It allows authentication using API tokens even when cookies are not available.
Environment
- Ubuntu 22.04.3 LTS (running via WSL)
- Docker Engine 26.0.0
- Amazon Linux 2023(OS of Docker container)
- PHP 8.2.15 (fpm-fcgi)
- Composer 2.7.6
- NGINX 1.24.0
- Laravel 11
Prerequisites
- A Docker container running a Laravel project (For details on how to run Laravel with NGINX, see this guide)
- Composer is installed in the Docker container (For how to install Composer, see this guide)
Table of Contents
1. Install Laravel Sanctum
First, install Laravel Sanctum.
Run the following command:
php artisan install:api
This will publish the personal_access_tokens
table.
You may be prompted to run the database migrations.
Type yes
to proceed, or no
to skip.
The default is yes
.
One new database migration has been published. Would you like to run all pending database migrations? (yes/no) [yes]:
If Composer is not installed, you’ll get the following error:
sh: line 1: exec: composer: not found
2. Enable API Token Generation
You need to enable the Eloquent model used for authentication to generate API tokens.
We’ll use the default User model that comes with a fresh Laravel installation.
Add the Laravel\Sanctum\HasApiTokens
trait to app/Models/User.php
.
User.php
:
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens; // Added
class User extends Authenticatable
{
// Add HasApiTokens
use HasApiTokens, HasFactory, Notifiable;
...
By adding the HasApiTokens
trait, the User model can now generate API tokens using the createToken
method.
3. Define Routes
Let’s define the routes to issue and authenticate using API tokens.
Open routes/api.php
, which was generated by running php artisan install:api
, and add the following routes:
The /user
route may already exist.
api.php
:
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
Route::post('/register', function (Request $request) {
// Add user to the database
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => $request->password
]);
// Issue API token
$token = $user->createToken('TestToken');
return ['token' => $token->plainTextToken];
});
The /user
route returns user information after authentication.
The auth:sanctum
middleware enables authentication using either cookies or API tokens.
If no auth cookies are found, API token authentication is used.
The /register
route registers a new user and returns an API token.
The token is issued using the createToken
method.
4. Test API Token Authentication
We’ll test token-based authentication using the routes defined above.
Let’s use the curl
command on Ubuntu to send HTTP requests to our Laravel project running on localhost:8080
.
At first, register a User and get an API Token.
Run the following command:
$ curl -X POST -H "Content-Type: application/json" -d '{"name":"Test", "email":"test@example.com", "password":"test"}' localhost:8080/api/register
Use any values for name
, email
, and password
in the request body.
The response should include an API token like this:
{"token":"1|RsrpmTepTJsUTfaosnVsE097WHaucLhZ5Vn7aPrV103b57d7"}
The token is stored in the personal_access_tokens
table in your database.
If you inspect the table, you’ll see the token stored as a SHA-256 hash:
+----+-----------------+--------------+-----------+------------------------------------------------------------------+-----------+---------------------+------------+---------------------+---------------------+
| id | tokenable_type | tokenable_id | name | token | abilities | last_used_at | expires_at | created_at | updated_at |
+----+-----------------+--------------+-----------+------------------------------------------------------------------+-----------+---------------------+------------+---------------------+---------------------+
| 1 | App\Models\User | 1 | TestToken | 0cb255c4ed077c5b0a3709b64810bb95dc97ad078793eaaef7f0c8f01bc9ef92 | ["*"] | 2024-05-21 09:18:26 | NULL | 2024-05-21 09:17:53 | 2024-05-21 09:18:26 |
+----+-----------------+--------------+-----------+------------------------------------------------------------------+-----------+---------------------+------------+---------------------+---------------------+
Next, use the token you received to authenticate the user.
Run the following command:
$ curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer 1|RsrpmTepTJsUTfaosnVsE097WHaucLhZ5Vn7aPrV103b57d7" localhost:8080/api/user
This sets the Authorization
header with the token using the Bearer scheme.
The response should return user information, indicating successful authentication:
{"id":1,"name":"Test","email":"test@example.com","email_verified_at":null,"created_at":"2024-05-21T09:17:53.000000Z","updated_at":"2024-05-21T09:17:53.000000Z"}