Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Joe5013's avatar

Sanctum SPA cookie authentication not working

Can someone give me step by step how to create a Laravel 12 api back end... using Sanctum SPA cookie authentication and planning for a react axios & vite front end. Include back end configuration. Include routes & AuthController for registration, login, logout

I'm trying to create a Laravel 12 api back end... using Sanctum SPA cookie authentication and planning for a react axios & vite front end. Not using a starter kit.

I just want to register a user, get the csrf-cookie, login the user, and logout. I can't log out using postman without errors.

I've created these routes Route::post('/register', [AuthController::class, 'register']); Route::get('/sanctum/csrf-cookie', 'Laravel\Sanctum\Http\Controllers\CsrfCookieController@show'); Route::post('/login', [AuthController::class, 'login']); Route::middleware('auth:sanctum')->group(function () { Route::post('/logout', [AuthController::class, 'logout']);

Postman responses Register: "201 success" Get cookie: "204 No Content" checking Manage Cookies I see 3 cookies present. One is un-named Login: for Header key I paste X-XSRF-TOKEN and the cookie. Send and I get "200 OK and "message: Logged in successfully". Logout: I do the same Header key but get 401 Unauthorized and "message": "Unauthenticated."

Perhaps my configuration settings are not correct. I've configured .env, config/cors, config/sanctum, & bootstrap/app

0 likes
2 replies
LaryAI's avatar
Level 58

Certainly! Here’s a step-by-step guide to set up Laravel 12 as an API backend using Sanctum SPA cookie authentication, suitable for a React (Axios & Vite) frontend. This will cover configuration, routes, and a basic AuthController for registration, login, and logout.


1. Install Sanctum

composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

2. Sanctum Middleware

In app/Http/Kernel.php, add Sanctum’s middleware to the api group:

'api' => [
    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    'throttle:api',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

3. Configure CORS

In config/cors.php:

'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['http://localhost:5173'], // Vite default port
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,

4. Configure Sanctum

In config/sanctum.php:

'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,localhost:5173,127.0.0.1,127.0.0.1:5173')),

In .env:

SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost,localhost:5173,127.0.0.1,127.0.0.1:5173

5. Set Session Driver

In .env:

SESSION_DRIVER=cookie

6. Routes

In routes/api.php:

use App\Http\Controllers\AuthController;

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::get('/sanctum/csrf-cookie', function () {
    return response()->noContent();
});
Route::middleware('auth:sanctum')->post('/logout', [AuthController::class, 'logout']);

7. AuthController Example

Generate controller:

php artisan make:controller AuthController

Then in app/Http/Controllers/AuthController.php:


8. Testing with Postman or Axios

Important:

  • Always call GET /sanctum/csrf-cookie first to set the XSRF-TOKEN cookie.
  • For POST requests (login, register, logout), send the X-XSRF-TOKEN header with the value from the XSRF-TOKEN cookie.
  • Make sure to send cookies with your requests (withCredentials: true in Axios, or enable cookies in Postman).

Example Axios config:

axios.defaults.withCredentials = true;
axios.get('http://localhost:8000/sanctum/csrf-cookie').then(() => {
  axios.post('http://localhost:8000/api/login', {
    email: '[email protected]',
    password: 'password'
  });
});

9. Common Issues

  • 401 on logout:
    This usually means the session cookie is not being sent. Make sure your frontend is sending cookies (withCredentials: true) and your CORS config allows credentials.
  • CSRF mismatch:
    Always fetch /sanctum/csrf-cookie before making POST requests.

10. Summary

  • Configure CORS and Sanctum for stateful SPA authentication.
  • Use auth:sanctum middleware for protected routes.
  • Always fetch CSRF cookie before login/logout.
  • Ensure cookies are sent with requests.

If you follow these steps, Sanctum SPA authentication should work with your React frontend and Laravel backend. If you still get 401 on logout, double-check that cookies are being sent and your CORS settings are correct.

JussiMannisto's avatar

If you just want a React front end, I highly recommend using InertiaJS. It's way simpler than using an API backend and an separate UI with its own router. Configuring Sanctum for a SPA can be confusing if you don't know how things are supposed to work.

The easiest way to get started is to install React + Inertia through the Laravel installer. You can delete the UI pages if you want to implement the UI from scratch. Just leave the scaffolding files.

Please or to participate in this conversation.