Fetch API with Cookie

CookiesFetch Api

Cookies Problem Overview


I am trying out the new Fetch API but is having trouble with Cookies. Specifically, after a successful login, there is a Cookie header in future requests, but Fetch seems to ignore that headers, and all my requests made with Fetch is unauthorized.

Is it because Fetch is still not ready or Fetch does not work with Cookies?

I build my app with Webpack. I also use Fetch in React Native, which does not have the same issue.

Cookies Solutions


Solution 1 - Cookies

Fetch does not use cookie by default. To enable cookie, do this:

fetch(url, {
  credentials: "same-origin"
}).then(...).catch(...);

Solution 2 - Cookies

In addition to @Khanetor's answer, for those who are working with cross-origin requests: credentials: 'include'

Sample JSON fetch request:

fetch(url, {
  method: 'GET',
  credentials: 'include'
})
  .then((response) => response.json())
  .then((json) => {
    console.log('Gotcha');
  }).catch((err) => {
    console.log(err);
});

https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials

Solution 3 - Cookies

Have just solved. Just two f. days of brutforce

For me the secret was in following:

  1. I called POST /api/auth and see that cookies were successfully received.

  2. Then calling GET /api/users/ with credentials: 'include' and got 401 unauth, because of no cookies were sent with the request.

The KEY is to set credentials: 'include' for the first /api/auth call too.

Solution 4 - Cookies

If you are reading this in 2019, credentials: "same-origin" is the default value.

fetch(url).then

Solution 5 - Cookies

Programmatically overwriting Cookie header in browser side won't work.

In fetch documentation, Note that some names are forbidden. is mentioned. And Cookie happens to be one of the forbidden header names, which cannot be modified programmatically. Take the following code for example:

  • Executed in the Chrome DevTools console of page https://httpbin.org/, Cookie: 'xxx=yyy' will be ignored, and the browser will always send the value of document.cookie as the cookie if there is one.
  • If executed on a different origin, no cookie is sent.
fetch('https://httpbin.org/cookies', {
  headers: {
    Cookie: 'xxx=yyy'
  }
}).then(response => response.json())
.then(data => console.log(JSON.stringify(data, null, 2)));

P.S. You can create a sample cookie foo=bar by opening https://httpbin.org/cookies/set/foo/bar in the chrome browser.

See Forbidden header name for details.

Solution 6 - Cookies

Just adding to the correct answers here for .net webapi2 users.

If you are using cors because your client site is served from a different address as your webapi then you need to also include SupportsCredentials=true on the server side configuration.

        // Access-Control-Allow-Origin
        // https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
        var cors = new EnableCorsAttribute(Settings.CORSSites,"*", "*");
        cors.SupportsCredentials = true;
        config.EnableCors(cors);

Solution 7 - Cookies

My issue was my cookie was set on a specific URL path (e.g., /auth), but I was fetching to a different path. I needed to set my cookie's path to /.

Solution 8 - Cookies

If it still doesn't work for you after fixing the credentials.

I also was using the :

  credentials: "same-origin"

and it used to work, then it didn't anymore suddenly, after digging much I realized that I had change my website url to http://192.168.1.100 to test it in LAN, and that was the url which was being used to send the request, even though I was on http://localhost:3000.

So in conclusion, be sure that the domain of the page matches the domain of the fetch url.

Solution 9 - Cookies

This works for me:

import Cookies from 'universal-cookie';
const cookies = new Cookies();

function headers(set_cookie=false) {
  let headers = {
    'Accept':       'application/json',
    'Content-Type': 'application/json',
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
};
if (set_cookie) {
    headers['Authorization'] = "Bearer " + cookies.get('remember_user_token');
}
return headers;
}

Then build your call:

export function fetchTests(user_id) {
  return function (dispatch) {
   let data = {
    method:      'POST',
    credentials: 'same-origin',
    mode:        'same-origin',
    body:        JSON.stringify({
                     user_id: user_id
                }),
    headers:     headers(true)
   };
   return fetch('/api/v1/tests/listing/', data)
      .then(response => response.json())
      .then(json => dispatch(receiveTests(json)));
    };
  }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKhanetorView Question on Stackoverflow
Solution 1 - CookiesKhanetorView Answer on Stackoverflow
Solution 2 - CookieszurfyxView Answer on Stackoverflow
Solution 3 - Cookieskore666View Answer on Stackoverflow
Solution 4 - CookiesalextrasteroView Answer on Stackoverflow
Solution 5 - CookiesIcebergView Answer on Stackoverflow
Solution 6 - CookiesMark DornianView Answer on Stackoverflow
Solution 7 - CookiesspiffytechView Answer on Stackoverflow
Solution 8 - CookiesSteve MoretzView Answer on Stackoverflow
Solution 9 - CookiesaarkerioView Answer on Stackoverflow