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

matthew_inamdar's avatar

CSRF mismatch with a SPA Vue app

Hi guys,

I'm following Jeff's current Vue 2.0 series and come across a problem which I'm not sure the best way to tackle is.

The CSRF token is mismatched after a logout/login - meaning the user cannot login or logout again unless they refresh the page to load the new CSRF token injected by blade.

I'm assuming on the POST request to login/logout I will need to pass back the new CSRF in the response and update this client side - it just seems a bit nasty...

Is there a simpler way to tackle this?

Many thanks, Mubeen.

0 likes
12 replies
rickbolton's avatar

What are you using for http requests? I've been using axios for a SPA and set like it will on Laravel 5.4

https://github.com/laravel/laravel/blob/develop/resources/assets/js/bootstrap.js#L33

/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */

window.axios = require('axios');

window.axios.defaults.headers.common = {
    'X-Requested-With': 'XMLHttpRequest'
};

And appears to be working fine. I've done a logout and login on another tab and it's still working on my original tab.

DmytroOlefyrenko's avatar

Did you set up X-CSRF-TOKEN for headers?

axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
mdaliyan's avatar

That doesn't help. Even we store csrf tokken in axios header, after it's expiration on server, our spa is unusable, unless we refresh the entire page and get a new csrf tokken from blade.

I think of some ways:

  1. every 10 seconds, our spa requests new csrf tokken from backend, and renew axios header. this works, but user loses connectivity on other instances of the app, if he/she has opened multiple tabs. so, this approach is not practical.

  2. server pushes new csrf tokken to user's sessions. this may work, but think of that extra work bothers me.

  3. please help master @jeff_way

bunnypro's avatar

i used to do this

  • create a route that return csrf_token()
  • create an interceptor that request new token whenever the request failed by token mismatch and re run the failed request, i also set limit for this like 3 times, when it reach the limit it will refresh the window.
mdaliyan's avatar

So the first approach with some improvements goes well if the route does not check the csrf token. Good point.

Api routes could be suitable. no extra middleware setup needed.

Thanks @bunnypro, but how is it different from not using token when everyone can get it?

  • Checking referrer is not a good idea, cause could be a mocked easily
  • Checking auth seems to work but again, we cannot login back the user that is logged out. we need to refresh the page again. Maybe I can exclude login route from CSRF protection, but it seems scary.

Am I missing something btw?

bunnypro's avatar

i think if your request comes from different host, the csrf token validation will fail.

or may be no, i don't really know how it works.

i used that method long time ago, and never use it again.

may be you can add a middleware to check is the incoming request comes from the same host.

mdaliyan's avatar

I already am able to detect mismatch token error. the question is what can i do to prevent that; or what to do when 419 happens.

in this situation every request to backend will be rejected. the only woking solution is to refresh the page and get the new token from blade. I hate to do that. users might have some unsaved form data on the page, that they might lose.

syropian's avatar

Just a note if you use some kind of token authentication such as JWT, you do not need CSRF validation, and should disable it.

tbtchan's avatar

did something like the following:-

window.axios.defaults.xsrfHeaderName = 'X-XSRF-TOKEN2'; window.axios.defaults.xsrfCookieName = 'XSRF-TOKEN2';

as a result X-XSRF-TOKEN doesnt appear in header anymore.. and some how my token mismatch error stops appearing.

I hope this is helpful. Try it out and do share if it does solve your token mismatch error.

green-raven's avatar

So, I was getting annoyed and did this TOKEN2 thing in my bootstrap.js file after i define window.axios, and the problem went away. Since I have a demo in the morning, that is nice. My question is, did this just magically remove all useful token checking? I'm not sure what this did exactly.

I also don't like that I have this problem in the first place. I'm using pagination. I get the first page, then the second page causes a token error, 1 second later, same axios call, same data, except "page: 2". Wasn't happening yesterday.

cootmcgoot's avatar

I approached this by modifying my logout controller to regenerate and return a new session token; then on the client/vue side, I updated my axios X-CSRF-TOKEN mapping with the new token. It works pretty effectively but hopefully someone has insight into why this might be a bad idea.

LoginController@logout

public function logout(Request $request) {
    // Laravel default implementation
    $this->guard()->logout();
    $request->session()->invalidate();
    
    // Added this
    $request->session()->regenerateToken();
    return $request->session()->token();
}

Vue Logout Method

axios.post('/logout')
    .then(({data}) => {
        axios.defaults.headers.common['X-CSRF-TOKEN'] = data;
    });

Please or to participate in this conversation.