laravel/sanctum
Laravel Sanctum is a lightweight authentication package for Laravel, designed for SPAs and simple APIs. It supports secure session-based auth for first-party SPAs and personal access tokens for API clients with minimal setup.
## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
Run these commands in your Laravel project to install Sanctum, publish its configuration, and create the required database tables.
Enable Sanctum Middleware:
Add Sanctum's middleware to your app/Http/Kernel.php under the $middleware and $middlewareGroups arrays:
'web' => [
// ...
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'auth:sanctum',
\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class,
],
First Use Case: Authenticate a SPA:
php artisan route:list
Look for Sanctum routes like sanctum/csrf-cookie and sanctum/token.sanctum/csrf-cookie to get a CSRF cookie, then use the login endpoint to obtain a token:
// Example using Axios
axios.post('/sanctum/csrf-cookie');
axios.post('/login', { email, password });
Generating Tokens:
Use the createToken method on your User model (or any model using HasApiTokens trait):
$token = $user->createToken('api-token-name', ['read', 'write']);
return response()->json(['token' => $token->plainTextToken]);
Revocating Tokens:
Revoke a token by calling revoke() on the token instance or using the revokeToken method on the user:
$user->tokens()->delete(); // Revoke all tokens
$token->revoke(); // Revoke a specific token
Token Scopes: Assign scopes to tokens for granular access control:
$token = $user->createToken('admin-token', ['admin', 'superuser']);
Protecting Routes:
Use the auth:sanctum middleware to protect API routes:
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Custom Guards:
Sanctum supports multiple guards. Configure them in config/auth.php:
'guards' => [
'sanctum' => [
'driver' => 'sanctum',
'provider' => 'users', // or a custom provider
],
'api' => [
'driver' => 'sanctum',
'provider' => 'admins',
'hash' => false,
],
],
Stateful Requests:
Sanctum can treat requests from specific domains as stateful (e.g., your SPA). Configure this in config/sanctum.php:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,127.0.0.1')),
CSRF Protection: Ensure your SPA sends the CSRF token with every stateful request. Sanctum automatically handles this for stateful domains.
Token Expiration:
Sanctum v3+ supports token expiration. Configure the expires_at column in your personal_access_tokens table and set it when creating tokens:
$token = $user->createToken('temporary-token', ['read'], now()->addHours(1));
Token Identification:
Use the plainTextToken property to identify tokens in your frontend:
// Store this token securely in your SPA
const token = response.data.token;
Token Last Used Tracking:
Enable last_used_at tracking in config/sanctum.php:
'track_last_used_at' => true,
CSRF Token Mismatch:
XSRF-TOKEN cookie is being sent with requests.Token Not Found:
TokenNotProvidedException or TokenMismatchException when making API requests.Authorization: Bearer <token> header is included in API requests.auth:sanctum middleware is applied correctly).Database Indexes:
personal_access_tokens table. Run migrations if you're upgrading from an older version:
php artisan migrate
Stateful Domains Misconfiguration:
config/sanctum.php under stateful. For local development, use:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,127.0.0.1,your-spa-domain.com')),
Log Token Creation/Revocations:
Override the createToken and revoke methods in your User model to log token events:
public function createToken($name = null, $abilities = [], $expiry = null)
{
$token = parent::createToken($name, $abilities, $expiry);
\Log::info("Token created for user {$this->id}: {$token->plainTextToken}");
return $token;
}
Inspect Middleware: Temporarily modify Sanctum's middleware to log requests:
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\App\Http\Middleware\LogSanctumRequests::class, // Custom middleware
Check Token Existence: Verify tokens exist in the database:
$tokens = \DB::table('personal_access_tokens')->where('tokenable_id', $user->id)->get();
Custom Token Model:
Extend Sanctum's PersonalAccessToken model to add custom logic:
namespace App\Models;
use Laravel\Sanctum\PersonalAccessToken as SanctumToken;
class PersonalAccessToken extends SanctumToken
{
public function customMethod()
{
// Add custom logic here
}
}
Update config/sanctum.php to use your custom model:
'token_model' => \App\Models\PersonalAccessToken::class,
Custom Token Generation:
Override the createToken method in your User model to customize token generation:
public function createToken($name = null, $abilities = [], $expiry = null)
{
return $this->tokens()->create([
'token' => \Str::random(40),
'abilities' => json_encode($abilities),
'created_at' => now(),
'expires_at' => $expiry,
]);
}
Custom Guard Logic: Extend Sanctum's guard to add custom authentication logic:
namespace App\Providers;
use Laravel\Sanctum\Guard;
use Illuminate\Http\Request;
class SanctumGuard extends Guard
{
public function user(Request $request)
{
// Custom logic to retrieve the user
return parent::user($request);
}
}
Bind the guard in a service provider:
public function register()
{
$this->app->bind(\Laravel\Sanctum\Guard::class, function ($app) {
return new \App\Providers\SanctumGuard($app['auth'], 'sanctum');
});
}
Token Prefix:
Sanctum tokens are prefixed with a checksum by default. Disable this in config/sanctum.php:
'use_checksum' => false,
Token Length: Sanctum tokens are shorter than Passport tokens (
How can I help you explore Laravel packages today?