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

beartown's avatar

How does Sanctum SPA authentication work exactly?

I'm not sure if the docs are very clear about that. For my understanding, SPA authentication just uses regular authentication via cookies, so nothing extra is needed. Does Sanctum add token authentication on top of that to make SPA authentication also possible via tokens?

In other words, if I don't need token-based authentication, can I just ignore Sanctum in my SPA entirely and base my authentication on the regular web guard?

0 likes
18 replies
martinbean's avatar

@beartown No, you need Sanctum to add cookie-based authentication to your SPA. Sanctum assists you in obtaining a CSRF token, ensuring the CSRF token and authenticated cookie are sent with asynchronous requests made by your SPA, and then decoding the cookie and authorising the user for each request. This wouldn’t happen without Sanctum as requests made by your SPA aren’t stateful (i.e. don’t include a session) so the web guard—which uses sessions to authenticate users—would fail, and not least because API routes are usually stateless (i.e. don’t use sessions), so you would get “Session store does not exist on request” errors if you just tried to use the standard web guard.

In a nutshell, Sanctum wouldn’t have been created if the normal web guard Just Worked™ for SPAs.

beartown's avatar

@martinbean thank you for your answer, however I still don't understand something. Why do I need decoding user, for example, in my SPA? My SPA's API is just route like any other, on same domain, so Laravel's session is being automatically passed via cookie, I don't need to help it.

As for the CSRF I also don't understand why they introduce an endpoint that returns the token. I need to check if the cookie returned by that endpoint actually works as CSRF protection or needs to be manually attached to the API requests (the docs say so). I prefer to render my CSRF token in my template and then read it from the <meta> tag, just like I would with a regular app. I guess this CSRF endpoint is meant to make the API more independent from SPA, but in my case, I don't care about that, as I won't use my API with other client apps.

Maelfjord's avatar

@beartown You only need to use the CSRF feature of Sanctum if your authentication relies on session cookies (because session cookies are vulnerable to CSRF). If you are using the other method of authentication by Sanctum, which is through personalized access tokens, you can ignore CSRF.

1 like
beartown's avatar

@Maelfjord thank you for your reply. Do I need Sanctum for CSRF protection though? It works just fine without Sanctum too.

I also don't quite get it why I need CSRF protection when there are CORS and SameSite protection layers as well. I could just skip sending session cookie when my app is requested from different domain.

I'm personally not a fan of CSRF, because sometimes it causes problems. Imagine having a form open in one tab and then having your website opened in another tab, logging out and back in there. You will be unable to send your form from the first tab. Maybe I'm being too dramatic, but it happened to me several times.

maxxd's avatar

That's how it's supposed to work, though. If you have a form behind a login, users that aren't logged in shouldn't be able to submit that form.

beartown's avatar

@maxxd they are not logged out. They logged out and then logged in, but in another tab, so they are logged in. It works fine without CSRF.

beartown's avatar

@jlrdw sure, however this document was created before CORS and SameSite as I understand it. If the client allows to block cookie access in different ways, I'd like to learn why CSRF is still so important.

beartown's avatar

@jlrdw and clicking on what exactly would make it insecure when we protest our app with CORS and SameSite?

And by the way, there is something wrong with this forums too (Safari, macOS). I need to ALWAYS refresh the site to post, otherwise it's submitting the form and the post is not published. I wonder if that't the problem with CSRF too.

jlrdw's avatar

@beartown

And by the way, there is something wrong with this forums too (Safari, macOS). I need to ALWAYS refresh the site to post, otherwise it's submitting the form and the post is not published. I wonder if that't the problem with CSRF too.

You need to let @jeffreyway know this through the support link or a post with the topic of feedback.

jlrdw's avatar

@beartown If you are doing an API only then you need to lookup and study CORS spoofing and how to take preventative measures. CORS is not security.

maxxd's avatar

@beartown The user is logged out, though - you said so yourself. Sure, they logged out in a different tab but they're still logged out of the site. If you are working at a cafe with a login-protected form in one tab and and another login-protected page in another tab and you log out of the site on the second tab in order to go grab another cup of coffee, some rando should not be able to sit in your spot, switch back to the form tab, and submit whatever damaging or dangerous input they want to. You should be logged out. Especially in this day and age, data security is a serious matter and should be treated as such.

beartown's avatar

@maxxd but this is not how it works in old fashioned websites, however I see your point.

beartown's avatar

@maxxd I did some digging and studied carefully how CSRF actually works in Laravel. I like Laravel's implementation of it - it only gets created once, when the app is first launched (and thus the session is created) and placed in the session payload under the _token key. No matter if we log in and/or log out million times - the CSRF token stays the same. It makes a lot of sense to me, even though it could be considered less secure compared to regenerating it timely or on some Auth events.

Also, I realized that this Sanctum SPA docs assume that your frontend is actually not Laravel. It's interesting, for example, that all calling /sanctum/csrf-token API endpoint does, is returning an empty response (204). Seriously, nothing else. It's only meant to "boot" the Laravel app for you (so in case of SPA, it's API layer) to make the CSRF cookie available for further API calls. That's a big relief for me now that I understand how it works exactly.

So to sum it up, as I understand it now, if my app is SPA made of Laravel frontend and Laravel backend, I do NOT need Sanctum, because everything will be handled out of the box securely.

Please or to participate in this conversation.