Reputation: 505
I am having issues in fetch sending cookies when I use the following js snippet in the console (in developer tools) of my browser (tried chrome, firefox and edge):
fetch('http://127.0.0.1:3010/check', {
credentials: 'include'
method: 'GET'
})
.then(res=>res.json())
.then(jsonobj=>{console.log(jsonbj)});
And here is my express code handling the api request:
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var cors = require('cors');
var app = express();
app.use(cors({
credentials: true,
origin: 'https://www.youtube.com'
));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.get('/check', (req, res)=>{
console.log(JSON.stringify(req.cookies));
res.json({
message: "COOL"
});
});
The fetch call is successful with the message COOL getting logged to the browser console. However, the NodeJS console prints empty objects {} or empty cookies.
For example, when I run the fetch request in the console of http://youtube.com/, I would like the browser to send cookies on my localhost to my express server (I did this to simulate cookie sending in cross-site request).
EDIT 1: Also some of the cookies on my localhost have SameSite unset and the mdn docs says that those cookies can be sent to server in cross site requests too:
The default behavior if the flag is not set, or not supported by the browser, is to include the cookies in any request, including cross-origin requests.
Either the snippet from mdn docs is wrong or the implementations of SameSite by browsers is inconsistent. I am confused.
EDIT 2: Also this page https://textslashplain.com/2019/09/30/same-site-cookies-by-default/ says
In Chrome 80 and later, cookies will default to SameSite=Lax. This means that cookies will automatically be sent only in a first party context unless they opt-out by explicitly setting a directive of None:
Are the mdn docs really incorrect then about the default value of SameSite?
EDIT 3: I have proposed an edit to the mdn docs and it has been accepted.
Upvotes: 8
Views: 7212
Reputation: 1489
Try typing in your ipaddress with the port in your browser instead of using localhost:8000. This fixed my problem and then for some reason I can re-use again localhost:8000.
I don't really know the issue that I faced but the solution that worked for me is no where to be found. I am leaving this here as a note in case anyone else will experience my problem. Maybe this really is a problem in the browser or somewhere.
Story:
Everything was working last year, in 3 weeks time,I re opened my project. Without changing anything in my codes, I expected everything to work. But fetch() is not sending cookies along. After following all of the possible solutions for cookies to be included in fetch(), still didn't work.
At some point, my team tried to input the IP address instead of 'localhost', then it worked. Even after reverting all the codes back to 3 weeks ago, it just works. Even using again the localhost:8000 works again. It's like nothing happened. We just needed to kick-start it by typing the IP address.
It has been a battle when in the end, I didn't really change anything in the codes. I hope this helps to someone. This might be a very weird scenario.
Upvotes: 0
Reputation: 505
Please see the edits on the question before moving with this answer. Now we can no-longer send cookies with cross-site requests if the cookies have the SameSite attribute unset, since the browsers have changed the default value of SameSite to lax. The following is a snapshot from the chrome patch notes (for the stable version 80, though the beta testing will be available for version 79 beta because google believes this change will be disruptive and may cause some web apps to behave incorrectly and hence shows the warning too) at https://support.google.com/chrome/a/answer/7679408#76:
Cookies with SameSite by default, and Secure SameSite=None cookies in Chrome 80 Starting in Chrome 80, cookies that do not specify a SameSite attribute will be treated as if they were SameSite=Lax. Cookies that still need to be delivered in a cross-site context can explicitly request SameSite=None. They must also be marked Secure and delivered over HTTPS. Policies will be made available for enterprises that need to configure Chrome to temporarily revert to legacy SameSite behavior.
Also similar behavior is displayed by Firefox and Edge currently. To send the cookies in cross origin requests, we have to explicitly set the SameSite attribute to None as:
Set-Cookie: key=value; SameSite=None; Secure
Also, note Secure is mandatory, else it will be treated as a Lax cookie. Use the None option only if you are really sure about what you are doing and handling cross-site request forgery accurately!!
I had proposed changes to the mdn docs of Http Cookie (https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) and the changes have been published. Now the mdn docs say:
Previously, the default behavior if the SameSite attribute is not set, or not supported by the browser, was to include the cookies in any request — including cross-origin requests.
However, new versions of browsers default to SameSite=Lax. In other words, cookies with no SameSite attribute set are now handled as if the value of the SameSite attribute is set to Lax — which means that cookies will automatically be sent only in a first party context. To specify that cookies are to be sent in both same-site and cross-origin requests, the value must be explicitly set to None.
Upvotes: 9