Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cookies not being stored with Fetch

I have read every other topic I could find on this and none of the solutions worked. I am using React + Redux + Express and attempting to store a JWT in a cookie as per:

https://auth0.com/blog/2015/09/28/5-steps-to-add-modern-authentication-to-legacy-apps-using-jwts/

In my Redux action I am sending the following request:

export function getCookie(token) {
  const config = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer ' + token
    },
    body: JSON.stringify({ token })
  };
  return fetch('http://127.0.0.1:4000/authorize-cookie', config)
   .then((res) => {
     return res.json();
   })
   .then((resJson) => {
     return resJson;
   })
   .catch(err => console.log('Error: ', err));
}

And on the server I am responding with...

app.post('/authorize-cookie', authenticate, (req, res) => {
  res.cookie('id_token', req.body.token, {
    maxAge: 360000
  });
  res.status(200).send({ message: 'Cookie set!' });
});

...where authenticate is a function that verifies the token.

Everything seems fine with my response header:

HTTP/1.1 200 OK
Set-Cookie: id_token=xxx.xxx.xxx; Max-Age=360; Path=/; Expires=Tue, 12 Jan 2016 01:24:03 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 25
ETag: W/"19-UA3htFr0PWczMQBN6T4NpA"
Date: Tue, 12 Jan 2016 01:18:03 GMT
Connection: keep-alive

But when I check the sources tab there's no cookie to be found. I've read about turning off httpOnly and secure and problems with using localhost. I've also tried in every major browser and no luck.

What's going on here?

like image 306
Andrew Avatar asked Jan 12 '16 01:01

Andrew


People also ask

Does fetch save cookies?

This enables you to create multiple fetch-cookie instances that use different cookie jars, essentially two different HTTP clients with different login sessions on you backend (for example). All calls to fetch will store and send back cookies according to the URL.

Are cookies sent on fetch requests?

Unless fetch() is called with the credentials option set to include , fetch() : won't send cookies in cross-origin requests. won't set any cookies sent back in cross-origin responses. As of August 2018, the default credentials policy changed to same-origin.

Why is cookie not being set?

Check out the OPTIONS response header ACCESS-CONTROL-ALLOW-CREDENTIAL whether it is set to true . If the server doesn't allow credentials being sent along, the browser will just not attach cookies and authorization headers. So this could be another reason why the cookies are missing in the POST cross-site request.


1 Answers

You encountered an interesting case. The thing is that behavior of fetch function is different rather than XMLHttpRequest. To work with cookies in fetch you should explicitly provide credentials option.

fetch('http://127.0.0.1:4000/authorize-cookie', {
    method: 'POST',
    body: JSON.stringify({token: token}),
    credentials: 'same-origin', // <- this is mandatory to deal with cookies
})

According to the article on MDN

Credentials: The request credentials you want to use for the request: omit, same-origin, or include. To automatically send cookies for the current domain, this option must be provided.

like image 78
just-boris Avatar answered Oct 06 '22 22:10

just-boris