I use the following pattern for stateless authentication with CSRF protection:
- Generate new JWT cookie for each handled request
- Generate new CSRF token for each handled request. Include it in the JWT token and in the response header
- Assert the CSRF token in the request header matches with the one in the JWT token
Client-side code extracts the CSRF token from each response and includes it in each request. The fresh token is stored in the browser session storage. I'm a bit concerned about the cookie and the token getting out of sync at the client side.
Considered the following simplified example
return axios.post(uri, payload, { headers: { 'X-CSRF-TOKEN': sessionStorage.getItem('X-CSRF-TOKEN') }})
.then(response => sessionStorage.setItem('X-CSRF-TOKEN', response.headers['X-CSRF-TOKEN']))
Is the browser cookie update and response handling an atomic operation given JavaScript's event loop model? Or is it possible for other asynchronous XHR requests to use stale token value for the present cookie in the marginal time window?