Laravel Sanctum is the simplest way to protect an API. It covers two common cases: token login for mobile apps and third-party clients, and cookie login for your own single-page app on the same domain.
Install Sanctum#
In Laravel 11 and 12, one command installs Sanctum, publishes its migration and creates routes/api.php:
php artisan install:api
Then add the HasApiTokens trait to your User model.
Issue tokens for mobile and external clients#
Create a login route that checks the credentials and returns a token:
Route::post('/login', function (Request $request) {
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
if (! Auth::attempt($credentials)) {
return response()->json(['message' => 'Invalid credentials'], 401);
}
$token = $request->user()->createToken('mobile', ['orders:read']);
return ['token' => $token->plainTextToken];
});
The client sends it on every request as Authorization: Bearer <token>.
Protect routes#
Route::middleware('auth:sanctum')->group(function () {
Route::get('/orders', [OrderController::class, 'index']);
Route::post('/logout', fn (Request $r) => $r->user()->currentAccessToken()->delete());
});
Limit what a token can do#
Abilities give each token only the access it needs. Check them where it matters:
if (! $request->user()->tokenCan('orders:read')) {
abort(403);
}
Cookie login for your own SPA#
For a Vue or Nuxt front end on the same domain, skip tokens. Call /sanctum/csrf-cookie first, then log in normally. Sanctum uses the session cookie, so there is no token to store in the browser.
Security checklist#
- Serve the API over HTTPS only.
- Add rate limiting to the login route.
- Set token expiry in
config/sanctum.php. - Delete tokens on logout and when a password changes.
- Never store tokens in
localStoragefor your own web app; use cookie login instead.




