$http request doesn't send cookies cross-domain in angular CORS

First of all I want to tell that I've read all the questions from Stack and everything related to CORS, but the implementation still doesn't work. My APP is built on top of angular crud demo:

So I have in the app config:

$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.withCredentials = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];

and I know they are correctly set (with debugging). In my "Security" app I'm doing a request for the current user, cross-domain:

return $http.get(LAYOUT_CONFIG.baseURL + '/current-user').then(function(response) {
      //service.currentUser = response.data.user;
      service.currentUser = response.data;
      return service.currentUser;
    });

I get these headers at the first request:

    Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:accept, origin, content-type, cookie
Access-Control-Allow-Methods:GET,POST
Access-Control-Allow-Origin:http://admin.vibetrace.com
Access-Control-Max-Age:1728000
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html; charset=utf-8
Date:Sun, 02 Jun 2013 11:07:49 GMT
P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"
Server:nginx/1.1.19
Set-Cookie:vibetrace.ssid=s%3A2lT2_N0-EevCJt7LbRlJ6Az1.d8xp99st%2F0RNV0VN2D4o4AJXNRT%2F%2F46v8PDVWSAbx%2Fw; Path=/; Expires=Mon, 30 Sep 2013 11:07:49 GMT
Transfer-Encoding:chunked
Vary:Accept-Encoding
X-Cache:MISS
X-Powered-By:Express

So Set-Cookie is there. However, the subsequent $http.get request (from angular) doesn't send the cookie which should have been previously set.

Accept:application/json, text/plain, */*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Host:app.vibetrace.com
Origin:http://admin.vibetrace.com
Pragma:no-cache
Referer:http://admin.vibetrace.com/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36

but here comes the interesting part. If I run the following code in the console:

$.ajax("https://app.vibetrace.com/current-user", {
            type: "GET",
            success: function(data, status, xhr) {               
            },
            xhrFields: {
                withCredentials: true
            },
            crossDomain: true
        });

the request header contains the cookies.

Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Cookie:fbm_245656478789760=base_domain=.vibetrace.com; __utma=199448574.828439508.1336934706.1361539088.1361819816.356; __utmc=199448574; __utmz=199448574.1361819816.356.354.utmcsr=tenlister.com|utmccn=(referral)|utmcmd=referral|utmcct=/index.php; connect.sid=s%3AZ1o9bIw0jBOmQwuhKJDG1San.%2BfshIsvupiRuK0pUJqm8EAMnMBCyxf%2Fk17cAVzcy31w; __utma=173003172.1796845739.1355503443.1369827921.1369833348.68; __utmc=173003172; __utmz=173003172.1369410587.66.5.utmcsr=stage.marketizator.com|utmccn=(referral)|utmcmd=referral|utmcct=/app/builder/; vibetrace.ssid=s%3AV6biojefu9r5DTGErKL5vYPi.KAlnWMUm8jZmPV0MpP%2FrgqwmkF6WuXEZZDyzJhozYCs
Host:app.vibetrace.com
Origin:http://admin.vibetrace.com
Pragma:no-cache
Referer:http://admin.vibetrace.com/

What I'm missing?


Solution 1:

Have you seen this? Communication between AngularJS and a Jersey Webservice which are on a different domain. Can't access correct session

Try passing a config object to $http that specifies withCredentials, that should work in all versions.

$http({withCredentials: true, ...}).get(...)

And the discussion here: https://github.com/angular/angular.js/pull/1209

Solution 2:

Setting withCredentials=true should work, and in particular the part where it does work with $ajax is vexing. It leads me to believe the problem is not in the client, but in a combination of what the server sends back and how you're testing it.

Are you sure you're testing on the same path with both jQuery and Angular?

The problem might be related to the cookie you get back from the server. If the path isn't set correctly, the browser will not send the cookies with the requests to other paths. This goes for other properties as well, but path is most likely.

This is would be unrelated to Angular configuration, but it could set you back a few hours nonetheless.

Other than that the only likely explanation is that you're using an old version of Angular, but given the detail of your question and links to other answers that seems unlikely to me.

Solution 3:

I see two different subdomains.

  • admin.vibetrace.com
  • app.vibetrace.com

Try to set the cookie for your main domain explicitly:

Set-Cookie:vibetrace.ssid=...; Domain=.vibetrace.com; Path=/; Expires=...

Reference: Wikipedia: HTTP Cookie - Domain and Path