Skip to main content

What is Sanctum?

Laravel Sanctum is a lightweight authentication package for SPAs (single-page applications), mobile apps, and simple APIs. Without needing deep knowledge of OAuth, you can issue and manage multiple API tokens per user. Sanctum solves two authentication problems:
Use SPA authentication when calling your API from your own SPA. Use API token authentication when mobile apps or third-party clients need to access your API. You can use either mode independently or both together.

Sanctum vs. Passport

Choose Passport only when you need to act as an OAuth2 provider for external services. For most applications, Sanctum is the right choice.

Installation and configuration

Install

Run the install:api Artisan command to set up Sanctum in one step:
This command automatically:
  • Installs the laravel/sanctum package
  • Publishes the personal_access_tokens table migration
  • Runs the migration

Add the HasApiTokens trait

Add the HasApiTokens trait to your User model:
This gives you access to methods like $user->createToken() and $user->tokens.

API token authentication

Token flow

Issue a token

Use the createToken() method to issue a token. Retrieve the plain-text token value from the plainTextToken property. The plain-text token is never stored in the database, so you must return it to the user immediately after creation.
The database stores a SHA-256 hashed version of the token.

Set scopes (abilities)

Assign abilities (scopes) to a token to restrict which operations it can perform:
Check token abilities when handling requests:

Check abilities with middleware

Register middleware aliases in bootstrap/app.php:
Apply the middleware to your routes:

Token expiration

By default, Sanctum tokens do not expire. Set an expiration time (in minutes) via the expiration option in config/sanctum.php:
You can also set per-token expiration:
When using token expiration, schedule a command to prune expired tokens regularly:

Revoke tokens


SPA authentication

SPA authentication uses session cookies, so there is no need to issue or manage tokens. It is ideal when calling your API from a first-party frontend (Vue, React, Next.js, etc.).
SPA authentication requires the SPA and API to share the same top-level domain (subdomains are fine). Requests must include an Accept: application/json header as well as a Referer or Origin header.

Enable the Sanctum middleware

Enable the statefulApi() middleware in bootstrap/app.php:

Configure first-party domains

Set your SPA’s domain in the stateful option in config/sanctum.php:

Configure CORS

If the SPA is on a different subdomain, configure CORS:
Set supports_credentials to true in config/cors.php:
Configure axios on the frontend as well:
Also configure the session cookie domain:

SPA authentication flow

1

Retrieve the CSRF cookie

Before logging in, call the /sanctum/csrf-cookie endpoint to initialize CSRF protection:
2

Send the login request

POST your credentials to the /login endpoint:
3

Make authenticated requests

After login, subsequent requests are automatically authenticated via the session cookie:

Protecting authenticated routes

Apply the auth:sanctum middleware to your routes. Unauthenticated requests will receive a 401 Unauthorized response. This single middleware handles both API token authentication and SPA authentication.

Practical example: login API with token response

A complete API token authentication example for a mobile app:
1

Create the login endpoint

2

Create authenticated routes

3

Send requests from the client


Testing

Use Sanctum::actingAs() in your tests to authenticate a user and specify which abilities to grant.

Summary

Add the HasApiTokens trait to your User model:
  • API token authentication: Use when clients without a session — such as mobile apps, third-party services, or CLI tools — need to access your API.
  • SPA authentication: Use when your first-party Vue, React, or Next.js frontend calls the API from the same domain (or subdomain). More secure and requires no token management.
Last modified on April 2, 2026