Storing CSRF token in NextJS headers while using JWT in cookies

I’m building a web app using Flask and NextJS. I’ve got JWT auth working with cookies, but I’m stuck on CSRF protection. I created a Flask route to provide a CSRF token, and now I’m trying to add it to my NextJS headers.

Here’s what I’ve tried:

const getNewCsrfToken = async () => {
  const response = await fetch('http://localhost:5000/csrf-token');
  const result = await response.json();
  return result.csrfToken;
};

const executeApiCall = async () => {
  const csrfToken = await getNewCsrfToken();
  const response = await fetch('http://localhost:5000/api', {
    method: 'GET',
    headers: { 'X-CSRF-Token': csrfToken }
  });
  // Process response
};

It works as expected in Insomnia, but when I test it in the browser, I keep receiving a ‘missing cookie token’ error. I’m sure I’m overlooking something simple. Any ideas on what might be going wrong? Thanks a lot for your help!

hey there, try sending the csrf token in every request.

also, double-check that the cookie gets set in the browser. sometimes 3rd-party cookies are blocked. using same domain for frontend and api might work. hope this hlps!

hmm, interesting problem! have u tried checking if the csrf token is actually being sent in the request headers? maybe use the browser’s network tab to see what’s going on. also, are u sure the cookie is being set correctly? sometimes there can be domain/path issues with cookies. what if u try using a different csrf implementation, like csurf middleware?

Your approach seems sound, but there might be a few issues to consider. Firstly, ensure that your Flask server is properly setting the CSRF token as a cookie. Check your server-side code to confirm this. Secondly, for cross-origin requests, you may need to enable credentials. Try adding ‘credentials: “include”’ to your fetch options. Lastly, make sure your CORS settings on the server allow for credentials and the specific origin of your NextJS app. If these don’t resolve the issue, you might want to log the entire request on the server side to see what’s actually being sent from the browser.