Nginx – Chrome ignores Set-Cookie directive from nginx reverse proxy

google-chromenginxreverse-proxy

I want to expose v1.2 of my API (and it's documentation) to users in China. The parent site mysite.mycompany.com is blocked for them, but 1.2.3.4 isn't, so I'm building a reverse proxy at that address that they can use to access my service.

I've configured an Nginx to reverse proxy http://mysite.mycompany.com to http://1.2.3.4

The proxy works great in Firefox and IE, but not in Chrome. Login is managed using cookies, but Chrome ignores the Set-Cookie header sent by the proxy during the login, and I don't understand why. This prevents Chrome users from logging in.

The parent site's response headers to the login request ( where Set-Cookie succeeds and login is successful) are

HTTP/1.1 302 Found
Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0
Content-Type: text/html; charset=UTF-8
Date: Tue, 12 Aug 2014 18:16:57 GMT
ETag: "1407867417"
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Last-Modified: Tue, 12 Aug 2014 18:16:57 +0000
Location: http://mysite.mycompany.com/user/me/apps
Server: Apache
X-Powered-By: PHP/5.3.15
Content-Length: 0
Connection: Keep-Alive
Set-Cookie: SESS25fe1d0b3b7239f403e22223da0614cf=Oo-PXr4XYQCFUKYUyZgX3UJpWADAhF_q7Xf-8gko3BU; expires=Thu, 04-Sep-2014 21:50:17 GMT; path=/; domain=.mysite.mycompany.com; HttpOnly

while the proxy site (where Set-Cookie fails and login is not successful) has the following response headers:

HTTP/1.1 302 Found
Server: nginx/1.4.7
Date: Tue, 12 Aug 2014 18:57:42 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Location: http://1.2.3.4/user/me/apps
Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0
ETag: "1407869862"
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Last-Modified: Tue, 12 Aug 2014 18:57:42 +0000
X-Powered-By: PHP/5.3.15
Connection: Keep-Alive
Set-Cookie: SESS25fe1d0b3b7239f403e22223da0614cf=DrY_4Y1NUPdIv9MsXPMjCr7Bzkq7DjyOmQPcNhetKXU; expires=Thu, 04-Sep-2014 22:31:02 GMT; path=/; domain=.1.2.3.4; HttpOnly

The interesting part of my nginx config is

http {
    # Ngnix defaults up to here then

    proxy_cache_path /var/spool/nginx keys_zone=CACHE:20m levels=1:2 inactive=6h max_size=1g;

    server {
        listen  80;


        location /v1.2/ {
                proxy_pass  http://api.mysite.mycompany.com/v1.2/;
                proxy_set_header  X-Real-IP    $remote_addr;
                proxy_set_header  X-Real-HOST  $host;
        }


        location / {
                proxy_pass      http://mysite.mycompany.com;
                # Required to prevent the host serving gzipped pages that can't be modified with sub_filter
                proxy_set_header        Accept-Encoding ''; 
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Real-HOST  $host;
                proxy_cookie_domain     mysite.mycompany.com     1.2.3.4;
                sub_filter      "mysite.mycompany.com"   "1.2.3.4";
                sub_filter_once off;
                proxy_cache     CACHE;
        }

    }

}

I've tried with the caching elements turned off, but it doesn't seem to change anything.

Do you have any idea why Chrome might be refusing to set the proxy's cookie?

Best Answer

Turned out not to be a problem with the nginx conf - that was fine.

The problem is due to the fact that Chrome only allows setting of cookies from fully-qualified domain names, not for IP addresses

https://code.google.com/p/chromium/issues/detail?id=56211

I bought a domain name, applied it to my server, and it worked. It required one change to the nginx config, which I should have done originally, which is to replace these two lines

            proxy_cookie_domain     mysite.mycompany.com     $host;
            sub_filter      "mysite.mycompany.com"   $host;
Related Topic