MadPhysicist
MadPhysicist

Reputation: 5831

Nginx Reverse Proxy with Gunicorn Treats Site Names Differently

We have a Django project that is served in production using Nginx and Gunicorn reverse-proxy setup. Everything seems to work except for one small detail. Somehow, the browser "sees" the following addresses as different sessions.

Suppose I log into the site using the example.com address. Then, if I visit https://www.example.com, the browser does not see that the user has logged in.

When I visit www.example.com, I get a 404 error in the browser from Nginx.

My suspicion is that this has something to do with the way Nginx or Gunicorn are setup. Any help on how to resolve this discrepancy is appreciated.

Nginx config:

server {

    root /home/example/mysite;

    # Add index.php to the list if you are using PHP
    index index.html index.htm;

    server_name example.com www.example.com;
    client_max_body_size 512M;
    location /static/ {
        alias /home/example/mysite/static/;
        expires 30d;
        add_header Vary Accept-Encoding;
        access_log off;
    }
    location /media {
        alias /home/example/mysite/media/;
        expires 30d;
        add_header Vary Accept-Encoding;
        access_log off;
    }
    location / {
        # try_files $uri $uri/ =404;
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $server_name;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_connect_timeout       6000;
        proxy_send_timeout          6000;
        proxy_read_timeout          6000;
        send_timeout                6000;
    }
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /home/ubuntu/ssl/example_com_chain.crt;
    ssl_certificate_key /home/ubuntu/ssl/server.key;
    #include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    #ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80 default_server;
    listen [::]:80 default_server;

    server_name example.com www.example.com;
    return 404; # managed by Certbot
}

Upvotes: 0

Views: 421

Answers (1)

cizario
cizario

Reputation: 4254

to redirect

http://www.example.com
http://example.com
https://www.example.com

to

https://example.com

you need to make changes in your nginx vhost config file like so:

# Resirect 'http www' and 'http non-www' traffic to 'https non-www'
server {

    listen 80;
    server_name example.com  www.example.com;
    return  301 https://example.com$request_uri;

}

# Resirect 'https www' traffic to 'https non-www'
server {

    listen 443 ssl;
    server_name www.example.com;
    return  301 https://example.com$request_uri;

}

# https://example.com
server {

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot

    server_name example.com;

    root /home/example/mysite;

    # Add index.php to the list if you are using PHP
    index index.html index.htm;

    client_max_body_size 512M;
    location /static/ {
        alias /home/example/mysite/static/;
        expires 30d;
        add_header Vary Accept-Encoding;
        access_log off;
    }
    location /media {
        alias /home/example/mysite/media/;
        expires 30d;
        add_header Vary Accept-Encoding;
        access_log off;
    }
    location / {
        # try_files $uri $uri/ =404;
        proxy_pass http://127.0.0.1:8080;  # HERE review this line it should be the server IP not localhost
        proxy_set_header Host $server_name;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_connect_timeout       6000;
        proxy_send_timeout          6000;
        proxy_read_timeout          6000;
        send_timeout                6000;
    }

    ssl_certificate /home/ubuntu/ssl/example_com_chain.crt;
    ssl_certificate_key /home/ubuntu/ssl/server.key;
    # include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    # ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

this thread may helps you https://www.digitalocean.com/community/questions/redirecting-https-www-domain-to-non-www-domain-with-nginx (my answer is based on)

and in your settings.py:

ALLOWED_HOSTS = [
    'example.com',  # https non-www
]

# SESSION_COOKIE_SECURE = True
# CSRF_COOKIE_SECURE = True

for more details see

Upvotes: 1

Related Questions