Skip to content

Instantly share code, notes, and snippets.

@Haythamasalama
Last active January 22, 2025 06:35
Show Gist options
  • Save Haythamasalama/76193a3de446418b7edb7aec7d3a9fa6 to your computer and use it in GitHub Desktop.
Save Haythamasalama/76193a3de446418b7edb7aec7d3a9fa6 to your computer and use it in GitHub Desktop.
Setting Up Authentication for Laravel Single Page Applications (SPA)

Setting Up Authentication for Laravel Single Page Applications (SPA)

Suppose you have two websites that require authentication:

  1. localhost:8000 (backend)
  2. localhost:3000 (frontend)

Configuration Steps:

  1. Allow origins for https://localhost:3000/
  2. Set the session domain to http://localhost
  3. 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

1. Update config/cors.php

<?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.

2. Update config/session.php

<?php

    'domain' => env('SESSION_DOMAIN', null),

Set the SESSION_DOMAIN to the main host, e.g., localhost.

3. Update config/sanctum.php

<?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:

  1. The domain in SANCTUM_STATEFUL_DOMAINS must be part of the same domain as SESSION_DOMAIN (e.g., localhost:3000 -> localhost).

  2. The default SESSION_LIFETIME is set to expire after 2 hours.


For more information, refer to the Laravel Sanctum SPA Authentication documentation.

@CrazyTapok-bit
Copy link

CrazyTapok-bit commented Jul 2, 2024

Hi
How to work with this if the api is on the subdomain api.example.com, and the frontend is on the main domain example.com? thank you

The fact is that everything works fine locally, but when I deploy, I get 419 with a CSRF token mismatch message. At the same time, the XSRF-TOKEN cookie is set, but on behalf of the subdomain, and I cannot get it to send in the header to the backend

@Doriiaan
Copy link

Doriiaan commented Dec 5, 2024

Thanks, good cheatsheet

@deanL-zuiderlicht
Copy link

Hi How to work with this if the api is on the subdomain api.example.com, and the frontend is on the main domain example.com? thank you

The fact is that everything works fine locally, but when I deploy, I get 419 with a CSRF token mismatch message. At the same time, the XSRF-TOKEN cookie is set, but on behalf of the subdomain, and I cannot get it to send in the header to the backend

@CrazyTapok-bit did you find a solution for this? I also have this issue after deployment. Locally it works fine. I cleared the caches but still a 419 error.

@CrazyTapok-bit
Copy link

@deanL-zuiderlicht my settings look like this:

APP_URL=https://api.example.com
FRONTEND_URL=https://example.com
SESSION_DOMAIN=.example.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment