Try Live
Add Docs
Rankings
Pricing
Docs
Install
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
Laravel Sanctum
https://github.com/laravel/sanctum
Admin
Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs, offering
...
Tokens:
7,010
Snippets:
24
Trust Score:
9.5
Update:
5 months ago
Context
Skills
Chat
Benchmark
79.5
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Laravel Sanctum Laravel Sanctum provides a featherweight authentication system for SPAs (Single Page Applications) and simple APIs. It offers API token authentication for mobile applications, third-party API consumers, and SPA authentication using Laravel's built-in cookie-based session authentication services. Sanctum allows each user of your application to generate multiple API tokens for their account, which can be granted specific abilities or scopes that specify which actions the tokens are allowed to perform. The package also includes middleware for verifying abilities, handling CSRF protection for SPAs, and managing token expiration with automatic pruning capabilities. ## API Token Creation Create personal access tokens for users with optional abilities and expiration times. ```php use App\Models\User; use Illuminate\Support\Facades\Hash; // Add the HasApiTokens trait to your User model class User extends Authenticatable { use Laravel\Sanctum\HasApiTokens; } // Create a token for a user $user = User::where('email', 'user@example.com')->first(); // Basic token creation with all abilities $token = $user->createToken('mobile-app'); $plainTextToken = $token->plainTextToken; // "1|5Rg3FGH...token...checksum" // Token with specific abilities $token = $user->createToken('admin-token', ['server:update', 'server:delete']); // Token with expiration date $token = $user->createToken('temporary-token', ['*'], now()->addDays(7)); // Store the plain text token to send to client // The token format is: {id}|{plainTextToken} return response()->json([ 'token' => $token->plainTextToken, 'type' => 'Bearer' ]); ``` ## Token Authentication Authenticate API requests using bearer tokens. ```php use Illuminate\Http\Request; // In your routes/api.php Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); }); // Client request example (curl) // curl -H "Authorization: Bearer 1|5Rg3FGH...token...checksum" \ // https://example.com/api/user // In your controller, access the current token Route::middleware('auth:sanctum')->get('/token-info', function (Request $request) { $user = $request->user(); $token = $user->currentAccessToken(); return [ 'token_name' => $token->name, 'abilities' => $token->abilities, 'last_used_at' => $token->last_used_at, 'expires_at' => $token->expires_at ]; }); // Custom token retrieval callback use Laravel\Sanctum\Sanctum; Sanctum::getAccessTokenFromRequestUsing(function ($request) { // Retrieve token from custom header or query parameter return $request->header('X-API-Token') ?? $request->query('api_token'); }); ``` ## Token Ability Checking Verify tokens have specific abilities before allowing actions. ```php use Illuminate\Http\Request; // Check abilities in your controller Route::middleware('auth:sanctum')->post('/servers/{id}', function (Request $request, $id) { if ($request->user()->tokenCan('server:update')) { // Update server return ['status' => 'Server updated']; } return response()->json(['error' => 'Insufficient permissions'], 403); }); // Using middleware to check all required abilities Route::middleware(['auth:sanctum', 'abilities:server:update,server:delete']) ->delete('/servers/{id}', function ($id) { // User token has both server:update AND server:delete abilities return ['status' => 'Server deleted']; }); // Using middleware to check for any ability (OR condition) Route::middleware(['auth:sanctum', 'ability:admin,moderator']) ->get('/dashboard', function () { // User has either admin OR moderator ability return view('dashboard'); }); // Check if token lacks an ability if ($request->user()->tokenCant('server:delete')) { return response()->json(['error' => 'Cannot delete servers'], 403); } ``` ## Token Management Manage and revoke user tokens programmatically. ```php use App\Models\User; // Get all tokens for a user $user = User::find(1); $tokens = $user->tokens; foreach ($tokens as $token) { echo $token->name . ' - Last used: ' . $token->last_used_at; } // Revoke a specific token $user->tokens()->where('id', $tokenId)->delete(); // Revoke current access token $request->user()->currentAccessToken()->delete(); // Revoke all tokens for a user $user->tokens()->delete(); // Revoke all tokens except current $user->tokens()->where('id', '!=', $request->user()->currentAccessToken()->id)->delete(); // Find and validate token manually use Laravel\Sanctum\PersonalAccessToken; $token = PersonalAccessToken::findToken($plainTextToken); if ($token && $token->can('server:update')) { $user = $token->tokenable; // Get the token owner // Perform action } ``` ## SPA Authentication Configuration Configure Sanctum for first-party SPA authentication using cookies. ```php // config/sanctum.php return [ 'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1' )), 'guard' => ['web'], 'expiration' => null, // minutes until token expires 'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''), 'middleware' => [ 'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class, 'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class, 'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, ], ]; // In your api.php routes Route::middleware(['auth:sanctum'])->group(function () { Route::get('/user', function (Request $request) { return $request->user(); }); }); // Protect routes with the stateful middleware in app/Http/Kernel.php 'api' => [ \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], // Frontend JavaScript example (Axios) // First, request CSRF cookie axios.get('/sanctum/csrf-cookie').then(response => { // Then login axios.post('/login', { email: 'user@example.com', password: 'password' }).then(response => { // Subsequent requests are authenticated via session cookie axios.get('/api/user').then(response => { console.log(response.data); }); }); }); ``` ## Database Migration Set up the personal access tokens table. ```php // Run migration php artisan migrate // The migration creates the personal_access_tokens table: Schema::create('personal_access_tokens', function (Blueprint $table) { $table->id(); $table->morphs('tokenable'); $table->text('name'); $table->string('token', 64)->unique(); $table->text('abilities')->nullable(); $table->timestamp('last_used_at')->nullable(); $table->timestamp('expires_at')->nullable()->index(); $table->timestamps(); }); // Custom token model use Laravel\Sanctum\Sanctum; use App\Models\CustomPersonalAccessToken; // In AppServiceProvider::boot() Sanctum::usePersonalAccessTokenModel(CustomPersonalAccessToken::class); class CustomPersonalAccessToken extends PersonalAccessToken { // Add custom methods or override behavior public function isExpired(): bool { return $this->expires_at && $this->expires_at->isPast(); } } ``` ## Middleware Protection Protect routes with ability-based middleware. ```php // In app/Http/Kernel.php, register middleware aliases protected $middlewareAliases = [ 'abilities' => \Laravel\Sanctum\Http\Middleware\CheckAbilities::class, 'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class, ]; // Require ALL specified abilities (AND condition) Route::middleware(['auth:sanctum', 'abilities:check-status,place-orders']) ->post('/orders', function () { // Token must have both 'check-status' AND 'place-orders' return ['status' => 'Order placed']; }); // Require ANY of the specified abilities (OR condition) Route::middleware(['auth:sanctum', 'ability:check-status,place-orders']) ->get('/orders', function () { // Token must have either 'check-status' OR 'place-orders' return ['orders' => []]; }); // Handle missing ability exceptions use Laravel\Sanctum\Exceptions\MissingAbilityException; class Handler extends ExceptionHandler { public function render($request, Throwable $exception) { if ($exception instanceof MissingAbilityException) { return response()->json([ 'error' => 'You do not have the required ability.', 'required_ability' => $exception->getMessage() ], 403); } return parent::render($request, $exception); } } ``` ## Token Pruning Remove expired tokens from the database. ```php // Run the prune command manually php artisan sanctum:prune-expired // Prune tokens expired for more than 48 hours php artisan sanctum:prune-expired --hours=48 // Schedule automatic pruning in app/Console/Kernel.php protected function schedule(Schedule $schedule) { $schedule->command('sanctum:prune-expired --hours=24')->daily(); } // Configure expiration in config/sanctum.php return [ // Global expiration time in minutes 'expiration' => 525600, // 1 year ]; // The prune command will delete tokens based on: // 1. Tokens with expires_at older than specified hours // 2. Tokens with created_at older than config expiration + hours ``` ## Testing with Sanctum Authenticate users in tests using actingAs helper. ```php use App\Models\User; use Laravel\Sanctum\Sanctum; use Tests\TestCase; class ApiTest extends TestCase { public function test_user_can_access_protected_route() { $user = User::factory()->create(); // Authenticate user with all abilities Sanctum::actingAs($user, ['*']); $response = $this->getJson('/api/user'); $response->assertStatus(200) ->assertJson(['id' => $user->id]); } public function test_user_with_limited_abilities() { $user = User::factory()->create(); // Authenticate with specific abilities Sanctum::actingAs($user, ['server:read', 'server:update']); // Should succeed $this->getJson('/api/servers')->assertStatus(200); // Should fail due to missing ability $this->deleteJson('/api/servers/1')->assertStatus(403); } public function test_unauthenticated_access() { // No authentication $response = $this->getJson('/api/user'); $response->assertStatus(401); } } ``` ## Custom Authentication Validation Add custom validation logic to token authentication. ```php use Laravel\Sanctum\Sanctum; // In AppServiceProvider::boot() Sanctum::authenticateAccessTokensUsing(function ($token, $isValid) { // Add custom validation logic // Example: Check if user is active if (!$token->tokenable->is_active) { return false; } // Example: Check IP whitelist if ($token->tokenable->ip_whitelist) { $allowedIps = json_decode($token->tokenable->ip_whitelist, true); if (!in_array(request()->ip(), $allowedIps)) { return false; } } // Return the validation result return $isValid && $token->tokenable->subscription_active; }); // Listen for token authentication events use Laravel\Sanctum\Events\TokenAuthenticated; Event::listen(TokenAuthenticated::class, function ($event) { $token = $event->token; // Log token usage Log::info('Token used', [ 'token_id' => $token->id, 'user_id' => $token->tokenable_id, 'ip' => request()->ip(), 'user_agent' => request()->userAgent() ]); // Check for suspicious activity if ($token->isBeingUsedFromMultipleLocations()) { $token->tokenable->notify(new SuspiciousActivityDetected($token)); } }); ``` ## Summary Laravel Sanctum is ideal for issuing API tokens to mobile applications, third-party API consumers, or for authenticating SPAs built with frameworks like Vue, React, or Angular. The token-based authentication approach provides a simple way to allow users to generate multiple API keys for different applications or purposes, each with its own set of granular permissions defined through abilities. For mobile apps and third-party integrations, tokens are issued and sent with requests as bearer tokens, while SPAs can leverage cookie-based session authentication for a seamless first-party experience. Integration with Laravel applications is straightforward through the HasApiTokens trait on your User model and the auth:sanctum middleware on protected routes. Sanctum handles token generation with SHA-256 hashing, automatic last-used tracking, flexible expiration strategies, and provides middleware for checking required abilities before executing actions. The package includes helpful utilities like the prune-expired command for cleaning up old tokens, event hooks for monitoring authentication activity, and testing helpers through the Sanctum::actingAs() method for writing comprehensive test suites with different permission scenarios.