AriehGlazer
AriehGlazer

Reputation: 2320

Browsers not sending back cookies when using CORS XHR

edit - looking at the cookies using Chrome web inspector, it seems like no matter what the expire value of the cookie is, the browser sets it as a session cookie and deletes it per request.

I am building a CORS example for a class I'm teaching, using Node.js and Express.

However, although cookies are being set from the server, they are not being sent back to the server on following requests. This pretty much means I can't use any trivial session manager.

Any idea what I'm missing here? Why doesn't the browser send cookies set by a domain back to that domain? Shouldn't this be happening automatically?

edit - some code examples: setting up the XHR request:

var xhr = new XMLHttpRequest();

xhr.open(method, url, true);
xhr.widthCredentials = true;

xhr.onreadystatechange = function(res){
    if (xhr.readyState == 4){
        cb(res,xhr);
    }
};

xhr.setRequestHeader("Content-Type",'application/json');

xhr.setRequestHeader('Accept','application/json');

xhr.send(JSON.encode({param:some_param})); 

server:

function allowCrossDomain(req,res,next) {  
    res.header('Access-Control-Allow-Credentials', true);
    res.header('Access-Control-Allow-Origin', req.headers.origin);
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type,Accept,X-Requested-With');

    if (req.method!='OPTIONS') return next();

    res.send(204);
}                 

//while configuring express
app.use(allowCrossDomain)

It is also worth mentioning that I have tried various npm middlewares that do the same thing with no observable difference

As for scenario:

  1. Make a CORS request using XHR
  2. Server sets a cookie, that is being successfuly sent back to the client (express session cookie)
  3. The next XHR request will not send that cookie back to the server, so express cannot identify the user, and so creates a new session cookie and so forth.

Upvotes: 29

Views: 26532

Answers (4)

H. J. Rhenals
H. J. Rhenals

Reputation: 145

I just had this problem, the solution in my case was add the path to the cookie, so when add the cookie you must use:

document.cookie = 'cookieName=cookieValue;path=/';

this way the browser will be able to send the cookie in the new request.

PS: You also need the xhr.withCredentials = true; if you are using cross domain request.

Upvotes: 7

Pointy
Pointy

Reputation: 413966

I don't really know anything about this other than what I've read, but according to the MDN docs there's a "withCredentials" property on the XHR object, and that needs to be set:

xhr.withCredentials = true;

By default, it's false. Without that flag being set, cookies are not transmitted and cookie headers in the response are ignored.

edit — I swear I read your question a couple times, but I totally missed your mention of the flag . Sorry. However, so as this isn't a total waste, I'll also mention that your server needs to be setting the "Access-Control-Allow-Credentials" flag to true in the response header, and "Access-Control-Allow-Origin" set to your current protocol + host + port.

Upvotes: 38

user210158
user210158

Reputation:

I had a similar problem, and it turned out that the browser settings were blocking third-party cookies (Chrome > Settings > Advanced Settings > Privacy > Content Settings > Block third-party cookies and site data). Unblocking solved the problem!

Upvotes: 3

Florian Margaine
Florian Margaine

Reputation: 60815

This happened to me before, and I can tell it's pretty stupid.

If you're using a virtual machine, you usually suspend it/resume it whenever you need it etc.

This means that the date of the virtual machine is usually some days late (or more) compared to the host, or any client you're using.

So when the server sets the cookie expire's date (usually a couple hours after current date), it is already expired on the client. Thus, the client doesn't keep it.

To update your date on your virtual machine, I suggest you just use ntpdate, or you can manually set the date to see if that's the problem:

# what's the date?
date
# You'll see if it's the problem already

# If it is, here is how to manually set it
date -set 2012-07-22 # yyyy-mm-dd
date -set 17:00:42 # hh:mm:ss

Upvotes: 5

Related Questions