From ffcf8294f1fc6f96b540ad38f7b4a5a8b350de9c Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Fri, 27 Mar 2020 12:11:33 +0100 Subject: [PATCH] fix: fetch CSRF cookie and set headers lazily (#38452) * fix: fetch csrf cookie and set headers lazily * fix: check cookie each call to keep it up to date Previously the cookie was checked once and never updated until the client was reloaded. Stale or absent cookies would generate incorrect tokens or no tokens, respectively, causing CSRF errors. --- client/src/redux/cookieValues.js | 1 - client/src/utils/ajax.js | 8 ++++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/client/src/redux/cookieValues.js b/client/src/redux/cookieValues.js index 475b34815a..016d499497 100644 --- a/client/src/redux/cookieValues.js +++ b/client/src/redux/cookieValues.js @@ -1,5 +1,4 @@ import cookies from 'browser-cookies'; -export const _csrf = typeof window !== 'undefined' && cookies.get('_csrf'); export const jwt = typeof window !== 'undefined' && cookies.get('jwt_access_token'); diff --git a/client/src/utils/ajax.js b/client/src/utils/ajax.js index b0776966e1..13be9430c9 100644 --- a/client/src/utils/ajax.js +++ b/client/src/utils/ajax.js @@ -1,7 +1,7 @@ import { apiLocation } from '../../config/env.json'; -import { _csrf } from '../redux/cookieValues'; import axios from 'axios'; import Tokens from 'csrf'; +import cookies from 'browser-cookies'; const base = apiLocation; const tokens = new Tokens(); @@ -10,7 +10,9 @@ axios.defaults.withCredentials = true; // _csrf is passed to the client as a cookie. Tokens are sent back to the server // via headers: -if (_csrf) { +function setCSRFTokens() { + const _csrf = typeof window !== 'undefined' && cookies.get('_csrf'); + if (!_csrf) return; axios.defaults.headers.post['CSRF-Token'] = tokens.create(_csrf); axios.defaults.headers.put['CSRF-Token'] = tokens.create(_csrf); } @@ -20,10 +22,12 @@ function get(path) { } export function post(path, body) { + setCSRFTokens(); return axios.post(`${base}${path}`, body); } function put(path, body) { + setCSRFTokens(); return axios.put(`${base}${path}`, body); }