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

PatrickCaneloDigital's avatar

[Inertia/Vue] 419 Token Mismatch Error on subcomponent right after login

I have a weird phenomenon I can't wrap my head around. My APP is laravel 11, jetstream, inertia/vue based

After Login I am correctly redirected to the Dashboard. The Dashboard fetches Data via Axios_GET (during setup) and displays them, at the same time the Dashboard has a subcomponent (vue) which also during setup makes an Axios POST Call to display GraphData. Right after login, the Dashboard correctly displays the GET data while the GraphSubcomponent always fails with a 419. Always just right after login! Only if I refresh the page the data get loaded correctly.

XHRPOST
http://localhost:63347/api/getSaldoSnapshots?portfolioId=1
[HTTP/1.1 419 unknown status 23ms]
message	"CSRF token mismatch."

OK, I can understand that a POST request is different than a GET and I probably could solve that issue by rewritig the Post request to an URL parsed get request, perhaps. But i want to understand: I dove deeper and the POST request is sending the X-CSRF-Token in the headers. So I quite don't get the Token Mismatch error in this context, because it's right after login! Would it perhaps to refresh the X-CSRF-Token right when landing in the dashboard, before the component is setup or something like that?

Btw: I also get a 419 Error (although Page Expired) when trying to access my login page right after a logout. I don't know if that is related but apparently something isn't quite right in my app (yet). I am using 3 layouts (non-login context, auth context and app context), the app-context is a SinglePageApp and vue-router based while Web & Auth are laravel router based.

0 likes
5 replies
Thriddle's avatar

Can you move the Axios POST from setup to the onMounted hook?

PatrickCaneloDigital's avatar

@Thriddle I could. And good advice, and I perhaps should try it. But, as I had the 419 error also during login, right after a logout, I am not sure if this is the reason or solution, also the user experience would not be great if the component mounts and then again gets a 419. I meanwhile work with a dirty hack: If the components which should not throw a 419 but do, then I trigger a simple location.reload. For the login component I do the same: During the setup of the login page I make a post request with no param to a /check419 url, if that returns a 419 the login would fail, so I trigger a reload before the user even enters the login data. Like this the user experience is not too bad. Not perfect but better than getting a 419 error for a unlogical reason.

Mega_Aleksandar's avatar

Do you regenerate the session or something on user login/logout? Or do you have any other middleware applied to the session tokens around the logged in session?

PatrickCaneloDigital's avatar

@Mega_Aleksandar nop... It's the default AuthenticatedSessionController destroy method. I even uncommented the if( $request->hasSession()) with no effect. My suspicion goes into the Inertia middleware (I do not use ssr though), because a page refresh solves everything, but always the first post after logout, and the first post after login fail (until the first page refresh). Then everything works as designed. I meanwhile make an early checkFor419 post call and if there is a 419 error I trigger a window.loaction.reload

gfucci's avatar

Exclude GET route from csrf verification in VerifyCsrfToken middleware

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array<int, string>
     */
    protected $except = [
      	// put here your get routes
    ];
}

Or pass through the "handle" method in VerifyCsrfToken, like

 public function handle($request, Closure $next)
    {
        if ($request->route()->named('login')) {
            if (! Auth::check() || Auth::guard()->viaRemember()) {
                $this->except[] = route('login');
            }
        }

        return parent::handle($request, $next);
    }

Please or to participate in this conversation.