DEV Community

Suhan Wijaya
Suhan Wijaya

Posted on • Originally published at Medium on

Missing cookie in HTTP request when using Fetch API

Image source: Programmer Humor

Here is an explainer of how cookies work. TLDR:

  • Browser sends HTTP request to server.
  • Server sends HTTP response with Set-Cookie: cookie=monster header, which sets the cookie in the browser.
  • Every subsequent request the browser sends to the server will have the Cookie: cookie=monster header.

I store a CSRF token in a cookie, which is used by the server to validate client-side HTTP POST 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 */ }
});
Enter fullscreen mode Exit fullscreen mode

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

import 'cross-fetch';

fetch('/some-route', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: { /* some payload */ }
});
Enter fullscreen mode Exit fullscreen mode

A bunch of users started getting 403s.

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:

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

import 'cross-fetch';

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

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

Today I learned.

📫 Hit me up on LinkedIn or Twitter!

Top comments (0)