Cookie missing in HTTP request when using Fetch API

Debugging: a classic mystery game where you are the detective, the victim, and also the murderer.

Image for post
Image for post
Image source: Programmer Humor

Here is an explainer of how cookies work. TLDR:

  • Browser sends HTTP request to server.
  • Server sends HTTP response with header, which sets the cookie in the browser.
  • Every subsequent request the browser sends to the server will have the header.

I store a CSRF token in a cookie, which is used by the server to validate client-side HTTP requests. The server responds with a 403 if the cookie is missing in the HTTP request.

On the client-side, I have been using the cross-fetch package via the ponyfill approach.

import fetch from 'cross-fetch';fetch('/some-route', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: { /* some payload */ }
});

One day, I decided to switch to the polyfill approach in order to use the native .

import 'cross-fetch/polyfill';fetch('/some-route', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: { /* some payload */ }
});

A bunch of users started getting 403s.

Image for post
Image for post
Image source: Know Your Meme

After scouring Stack Overflow and the interwebs (and many tears later), the answer was in the MDN docs all along:

Image for post
Image for post

The users getting 403s were using browsers older than the versions listed above. So this was the fix:

import 'cross-fetch/polyfill';fetch('/some-route', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: { /* some payload */ },
credentials: 'same-origin' // the fix
});

You might ask: what about Internet Explorer, your favorite problem child? Well, since it supports nothing, the polyfill kicks in with a version of that sets as the default credentials policy, so no 403s.

Today I learned.

📫 Hit me up on LinkedIn or email!

Written by

Right-brained techie passionate about coding, product, UX, and fun adventures with my family. Let’s connect on linkedin.com/in/suhanwijaya

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store