Laravel Sanctum is the official, lightweight API authentication package built into Laravel. It handles token issuance, route protection, and token revocation with minimal setup — making it the right choice for almost every Laravel REST API and mobile backend.
This tutorial covers a complete Sanctum setup from scratch: installation, User model configuration, protected routes, a full AuthController, and how to make authenticated requests. All examples work with Laravel 12.
What is Laravel Sanctum?
Sanctum provides API token authentication using plain-text tokens stored in a personal_access_tokens database table. Unlike JWT, tokens aren't self-contained — each request does a quick database lookup to validate. The trade-off is instant, reliable token revocation.
| Feature | Sanctum | Passport | JWT (tymon) |
|---|---|---|---|
| Best for | Your own API | OAuth2 / third-party | Stateless / microservices |
| Token storage | Database | Database | Client-side only |
| Setup complexity | Simple | Complex | Medium |
| Built into Laravel | ✅ Yes | ❌ No | ❌ No |
| Token revocation | ✅ Easy | ✅ Yes | ⚠️ Hard |
| SPA cookie auth | ✅ Yes | No | No |
For most Laravel REST APIs, Sanctum is the right choice. Use Passport only when you need a full OAuth2 server for third-party developers.
Step 1: Install Laravel Sanctum
On Laravel 11 and 12, Sanctum is included by default. For Laravel 10 and below, install it manually:
Terminalphp artisan migrate if you haven't already — the personal_access_tokens table migration is included.
Step 2: Add HasApiTokens to the User Model
Add the HasApiTokens trait to your User model. This gives the model the createToken(), tokens(), and currentAccessToken() methods:
Step 3: Set Up API Routes
Define your public and protected routes in routes/api.php. The auth:sanctum middleware guards any route that requires a valid token:
Step 4: Build the AuthController
This controller handles registration, login, logout, and the authenticated user endpoint. The key line is createToken()->plainTextToken — this generates and returns the token the client will store and send on future requests:
Step 5: Make Authenticated Requests
After login, the client receives a plain-text token. Send it in the Authorization header as a Bearer token on every protected request:
1|randomstring. The number before the pipe is the token ID in the database. Always send the full string including the numeric prefix.
Token Abilities (Optional Scopes)
Sanctum supports token abilities — a simple alternative to OAuth scopes. You can restrict what each token is allowed to do:
Token abilitiesRevoking Tokens
Because tokens are stored in the database, revocation is instant. This is one of Sanctum's biggest advantages over JWT — no denylist needed, just delete the row:
Revocation optionsSetting Token Expiry
Set the expiration value in config/sanctum.php. The value is in minutes:
Common Issues & Fixes
401 Unauthenticated on every request
Make sure you're sending the token as Authorization: Bearer YOUR_TOKEN — not as a query parameter or cookie. Also confirm the HasApiTokens trait is on your User model and migrations have run.
CORS errors from a frontend SPA
Add your frontend URL to config/cors.php:
Missing personal_access_tokens table
Run php artisan migrate and confirm the table exists in your database. On Laravel 11/12 this migration is included automatically.
Frequently Asked Questions
Does Laravel Sanctum use JWT tokens?
No. Sanctum uses plain-text tokens stored in your database, not JWT. JWT tokens are stateless and self-contained; Sanctum tokens require a database lookup on each request. The trade-off is that Sanctum tokens are much easier to revoke instantly. See the full breakdown in Laravel Sanctum vs JWT.
When should I use Sanctum vs Passport?
Use Sanctum when you're building an API for your own frontend — SPA or mobile app. Use Passport only when you need a full OAuth2 server to issue tokens to third-party developers. Passport is significantly more complex to set up and maintain.
Can I use Sanctum for SPA cookie authentication?
Yes — Sanctum also supports cookie-based SPA authentication using CSRF tokens. For a REST API or mobile backend, token-based authentication as shown in this tutorial is the standard approach.