Suppose you have two websites that require authentication:
- localhost:8000 (backend)
- localhost:3000 (frontend)
- Allow origins for
https://localhost:3000/ - Set the session domain to
http://localhost - Configure Sanctum stateful domains for
http://localhost:3000
| Setting | Value | Format |
|---|---|---|
| FRONTEND_URL | https://localhost:3000 |
schema://host:port without / at the end of the URL |
| SESSION_DOMAIN | localhost |
host |
| SANCTUM_STATEFUL_DOMAINS | localhost:3000 |
host:port |
<?php
return [
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => [env('FRONTEND_URL', 'http://127.0.0.1:8000')],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
];In allowed_origins, add the FRONTEND_URL in the format schema://hostname, such as https://localhost:3000.
<?php
'domain' => env('SESSION_DOMAIN', null),Set the SESSION_DOMAIN to the main host, e.g., localhost.
<?php
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),Add SANCTUM_STATEFUL_DOMAINS only for the main host, e.g., localhost.
Update .env file
APP_NAME=
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8000
FRONTEND_URL=http://localhost:3000
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:3000
// etc...
Notes:
-
The domain in
SANCTUM_STATEFUL_DOMAINSmust be part of the same domain asSESSION_DOMAIN(e.g.,localhost:3000->localhost). -
The default
SESSION_LIFETIMEis set to expire after 2 hours.
For more information, refer to the Laravel Sanctum SPA Authentication documentation.
Hi
How to work with this if the api is on the subdomain
api.example.com, and the frontend is on the main domainexample.com? thank youThe fact is that everything works fine locally, but when I deploy, I get 419 with a
CSRF token mismatchmessage. At the same time, theXSRF-TOKENcookie is set, but on behalf of the subdomain, and I cannot get it to send in the header to the backend