Nginx Proxy – Cookies Not Set Issue

cookiesnginxproxypass

Here's my situation, I have a Rails 4 app that can be accessed by multiple domains, depending on the domain, the content changes.

Say the main domain is domain1 and all the other domains just use Nginx's proxy_pass to forward the requests to domain1, this is all working fine except that the session or other cookies are not set for domain2.

In my Rails app i've created a middleware that sets dynamically the domain for the session according to what domain is accessing the app using the content of the CUSTOMHEADER header, and I can see in the Set-Cookie header that the cookie domain is correct so I'm thinking my problem is in my Nginx configuration, but sadly my Nginx knowledge is quite limited.

Nginx config

The following is an example host file for domain2 (one of the example domains where the cookies are not set):

server {
  listen   80;

  server_name domain2.com;
  rewrite ^(.*) http://www.domain2.com$1 permanent;
}

server {
  listen   80;
  server_name www.domain2.com;

  location /assets/ {
    proxy_pass                      https://main.domain1.com/assets/;
    proxy_set_header                X-Real-IP       $remote_addr;
    proxy_set_header                X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header                Cookie $http_cookie;
    proxy_set_header                CUSTOMHEADER www.domain2.com;
    proxy_pass_request_headers      on;
  }

  location /some_path/ {
    proxy_pass                      https://main.domain1.com/some_path/;
    proxy_set_header                X-Real-IP       $remote_addr;
    proxy_set_header                X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header                Cookie $http_cookie;
    proxy_set_header                CUSTOMHEADER www.domain2.com;
    proxy_pass_request_headers      on;
  }

  location / {
    proxy_pass                      https://main.domain1.com;
    proxy_set_header                X-Real-IP       $remote_addr;
    proxy_set_header                X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header                Cookie $http_cookie;
    proxy_set_header                CUSTOMHEADER www.domain2.com;
    proxy_pass_request_headers      on;
    rewrite ^/(.*)$ /sites/some-id/$1 break;
  }
}

when opening up a page in the browser and inspecting the headers i get the following (in Chrome):

Response Headers

HTTP/1.1 200 OK
Server: nginx/1.10.2
Date: Mon, 05 Nov 2018 22:21:45 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Vary: Accept-Encoding
Status: 200 OK
Cache-Control: max-age=0, private, must-revalidate
Strict-Transport-Security: max-age=31536000
X-XSS-Protection: 1; mode=block
X-Request-Id: 33d26df0-f44c-4ff5-9513-62aaade8c581
ETag: W/"3dd8553b2a02cfc9f85a609c5f90bafb"
X-Frame-Options: SAMEORIGIN
X-Runtime: 0.025616
X-Content-Type-Options: nosniff
Set-Cookie: _myapp_session=dmNFR2...3ae445b; domain=www.domain2.com; path=/; secure; HttpOnly
X-Powered-By: Phusion Passenger 5.1.2
Content-Encoding: gzip

Request Headers

GET /login HTTP/1.1
Host: www.domain2.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://www.domain2.com/bla
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,pt;q=0.8,fr;q=0.7
If-None-Match: W/"09c9ac3842dd3942a006b9000bd7a29d"

As you can see the Response contains the Set-Cookie header and the cookie has the correct domain, and yet the cookie is never set by the browser, and you will also notice that the Request doesn't have the Cookie header, although that might just be because there is no cookie to send.

Note 1: I've also tried setting the following headers in the response coming from the Rails app, but that didn't help:

  • Access-Control-Allow-Origin: *
  • Access-Control-Allow-Credentials: true

Note 2: I know the browser will not create the cookie if it's oversized but the cookie size should be far from the maximum, so I don't think that's the problem here.

The session works fine when accessing the main domain (http://main.domain1.com), what am I missing here? I feel like I'm lacking some theoretical knowledge about Nginx or web servers in general that is preventing me from getting this right but I've been struggling with this for 3 days, tried all kinds of headers and different combinations and so far all my research is fruitless.

Best Answer

Finally solved this, the problem was that the main.domain1.com was using SSL while the other domains weren't, I tried disabling SSL on the main domain and it worked, the other domains finally had session cookies, I'll have to see if it works once I add SSL to the other domains and re-enable it on the main domain but i'll cross that bridge once I get there.