2

I need Laravel Sanctum to support both SPA and Mobile App (Bearer) authentication. The issue is that I can't get both to work in parallel.

The SPA works perfectly fine, but the mobile app throws a "CSRF token mismatch error" when calling any protected endpoints. The issue seems to be the Origin header.

I noticed that the production mobile app's Origin header is "http://localhost/". If in Postman I use that value as the Origin header, the endpoints throw the same CSRF token mismatch error.

enter image description here

If I change the Origin header to anything else, everything works perfectly.

enter image description here

These are the contents of my config/sanctum.php:

'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
    '%s%s',
    'localhost,localhost:3000,localhost:8080,127.0.0.1,127.0.0.1:8000,::1',
    env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),

"localhost" is already there so I am not sure why the Bearer token auth fails when the Origin = "http://localhost"

I tried setting my .env SANCTUM_STATEFUL_DOMAINS to "http://localhost", and this makes the Mobile App work perfectly, but then it breaks the SPA.

1 Answer 1

7

Turns out the Origin and Referer headers tell Laravel that it should use the cookie-based authentication system and ignore the Bearer token. The code that handles this is in vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStatefull.php

To force Laravel to NOT use cookie-based authentication on my mobile app, I had to set my production .env SANCTUM_STATEFUL_DOMAINS to the actual production domain of the SPA. It basically tells Laravel "you should only use cookie-based auth on this domain".

If you leave SANCTUM_STATEFUL_DOMAINS unset, it will default to "localhost", which is the Origin domain of any Android app. Meaning, the Android app will attempt to use cookie auth, which is not what anybody wants.

Sign up to request clarification or add additional context in comments.

1 Comment

It would be very useful to know the Laravel version you were using at that time, because in the version 11 it is much simpler to configure the requests from SPAs and Mobile Apps: laravel.com/docs/11.x/sanctum#sanctum-middleware

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.