Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.
like image 631
AriehGlazer Avatar asked Jul 22 '12 14:07

AriehGlazer


People also ask

How do I send cookies in XHR request?

open("GET", url, false); xhr. withCredentials = true; xhr. setRequestHeader('Cookie', 'mycookie=cookie'); xhr. send();

Why is my cookie not being sent?

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.

Are cookies sent with image requests?

Yes cookies are sent on all requests. This includes "img" and "script" as well as XMLHttpRquest calls from javascript and can be a security issue on script tags as scripts loaded by one website can load scripts from another site and will send their authentication cookies too.


2 Answers

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.

like image 83
2 revs, 2 users 93% Avatar answered Oct 13 '22 17:10

2 revs, 2 users 93%


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 
like image 40
Florian Margaine Avatar answered Oct 13 '22 19:10

Florian Margaine