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_DOMAINS
must be part of the same domain asSESSION_DOMAIN
(e.g.,localhost:3000
->localhost
). -
The default
SESSION_LIFETIME
is 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 mismatch
message. At the same time, theXSRF-TOKEN
cookie is set, but on behalf of the subdomain, and I cannot get it to send in the header to the backend