I have a SPA application that is powered via axios. Now, I originally noticed that the CRSF token was being dropped randomly which we identified as a race condition when two requests fired concurrently. I since changed the storage mechanism for sessions to the database and added atomic blocking to my routes and disabled the requirement for CSRF for routes that where not "action" routes.
Now, what is interesting, I get a 401 unauthenticated instead (randomly). I found a post online about reattempting to capture all the new session/token so I wrote the following:
let retries = [];
const sessionHandler = async error => {
if (error.response && (error.response.status === 419 || error.response.status === 401)) {
const uri = error.response.config.url;
const data = error.response.config.data;
// I use nothing from this endpoint, its simply to allow
// axios to get the CSRF token
const endpoint = '/session/user-config';
// Push to retries
retries.push({uri: uri, data: data});
// After exhausting retries, force refresh
if (retries.filter(attempt => attempt.uri === uri).length > 3 || retries.filter(attempt => attempt.uri === endpoint).length > 3) {
window.location.reload();
}
// Attempt to obtain new token
return await axios.get(endpoint).then(async () => {
// Attempt to fulfill request
return await axios.post(uri, data).then(response => response);
});
}
return Promise.reject(error);
};
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
axios.interceptors.response.use(response => {
// Remove any attempts after a successful request
retries.filter(attempt => attempt.uri = response.config.url).forEach(attempt => {
retries.slice(retries.indexOf(attempt), 1);
});
return response;
}, sessionHandler);
This successfully (70% of the time) grabs a new token should any 419 errors get thrown. Now, for the other 30%, it loops and eventually reloads the page. During this reload, after a 401 Unauthenticated 3 times, it redirects to login.
This can happen within the first 2 minutes of logging in sometimes. I have increased the session lifetime to 1 year to debug, I have tried everything locally to reproduce this, as well as on dev/test servers and yet it seems to be only effecting the production server.
I've tried to check all the configuration for differences but none can be found. I cannot find any known issues surrounding this and the 70% is not a solution but more a duck-tape fix. Does any one know if there is something additional I can do to laravel or axios to prevent this issue?
This happens randomly, I can click around really fast for ages and it won't happen, then randomly, it will happen.
Update: I have noticed that every request, made by axios, updates the local cookie value of the session, I'm unsure if this is normal behaviour but potentially it could be encountering a read/write issue? Is it even possible to add blocking to cookies?
When watching the request, both the CSRF and session cookies are sent. The request appears fine but yet it results in either a 419 CSRF token issue or a 401 Unauthenticated. I then resend the request and it works fine - it is totally randomly failing.
Below is an example of what can been seen, one request got a 401 response code but yet all the others worked perfectly fine.
Sometimes, all of these might 401. Inside the request, the CSRF token and laravel_session is sent in the headers and cookies. No signs of anything missing or dropping out as seen below in the request:
419 Request:
401 Request:
Another update, after using the debugger tools, I can see Axios runs into an exception during a 401:
The full exception is detailed below but only triggers during a 401:
TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them



