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

stacker's avatar

419 CSRF token mismatch but if I comment 'EnsureFrontendRequestsAreStateful' it's working

For a few days I'm having hard time figuring out why I can either use my Laravel API with CORS error message, or not use it at all with 419 CSRF mismatch error.

This is the case: I have a react registration page that sends POST request to http://localhost:8080/api/register, and the route is defined in Laravel in routes/api.php, NOT routes/web.php

At first I tried to follow the docs but got stuck with Error 419: CSRF token mismatch.

This is my axios call from my frontend (register.jsx):

// get CSRF token first
useEffect(() => {
    axios.get('http://localhost:8080/sanctum/csrf-cookie').then(response => {
        console.log(JSON.stringify(response))
    });
}, []);

        axios({
            method: 'post',
            url: 'http://localhost:8080/api/register',
            withCredentials: true,            
            data: {
                email: email,
                password: password
            }
        })
        .catch (error => {
        console.log("Error: ", error.response);
    });

I have no idea why it doesn't work, I think i tried all the combinations in the cors.php file and that didn't help. Also, when I look in the cookies in use in the browser, I did not see the CSRF cookie.

Then I commented out the following line from Kernel.php in the Laravel project (Which is the opposite of what is said in the docs. By default it was commented out, then I uncommented it and now commented again)

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

And now it works! I am able to create a user. But, now there is a new error (although it does create the user):

Access to XMLHttpRequest at 'http://localhost:8080/api/register' from origin 'http://localhost:3000' has >been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested >resource. Error: undefined POST http://localhost:8080/api/register net::ERR_FAILED

**I already set 'supports_credentials' => true in cors.php

What should I do?

Thanks

0 likes
7 replies
SilenceBringer's avatar

@stacker just follow the steps in docs. and don't forget

Finally, you should ensure your application's session cookie domain configuration supports any subdomain of your root domain. You may accomplish this by prefixing the domain with a leading . within your application's config/session.php configuration file:

'domain' => '127.0.0.1',

and uncomment EnsureFrontendRequestsAreStateful

1 like
iferas93's avatar

Hi @stacker,

Check these following variables into your '.env' file

  • uncomment EnsureFrontendRequestsAreStateful

  • SANCTUM_STATEFUL_DOMAINS="frontend_url" here you need your frontend URL

  • SESSION_DOMAIN also you can config it from config/session.php You may accomplish this by prefixing the domain with a leading . within your application's if you want supports any subdomain of your root domain

1 like
shaungbhone's avatar

You need to check your SESSION_DOMAIN. This is my cors.php file with the login page.

'paths' => ['api/*', 'sanctum/csrf-cookie', 'login'],

jsfile

async login() {
      await axios.get('sanctum/csrf-cookie')
}
1 like
stacker's avatar

I have these configured already. Except I am using axios.get('http://localhost:8080/sanctum/csrf-cookie') instead, because the front end and the backend are on different ports. When I try axios.get('sanctum/csrf-cookie'), it doesn't work, it tries to use the frontend base url localhost:3000 instead of localhost:8080

I noticed that Axios does not send the TOKEN back in the subsequent POST requests headers! Could that be the problem? I do get XSRF-TOKEN= cookie created when I use axios.get('http://localhost:8080/sanctum/csrf-cookie') , but from some reason Axios does not send it automatically on subsequent requests (I see on the Network tab - maybe that's because I'm on different ports?)

shaungbhone's avatar

It's a unique issue. @stacker

make this RedirectAuthenticated.php

foreach ($guards as $guard) {
  if (Auth::guard($guard)->check()) {
        if ($request->wantsJson()) {
             return response(null);
            }
          return redirect(RouteServiceProvider::HOME);
            }
        }

Maybe. It's work.

1 like
stacker's avatar

It doesn't work either. I was told that the issue is because they are different domains, not sub-domains of each other, i.e localhost:3000 and localhost:8080.

And that I should somehow proxy the requests from the front end to the backend Maybe the solution is Passport and not Sanctum in this case since they are on different domains?

Also, I noticed that calling 'http://localhost:8088/sanctum/csrf-cookie' does not save the token in the browser. The browser rejects it from some reason. I do see the token in the Network tab, but the cookie is not set.

1 like

Please or to participate in this conversation.