【问题标题】:Nginx Reverse Proxy with Gunicorn Treats Site Names Differently带有 Gunicorn 的 Nginx 反向代理对站点名称的处理方式不同
【发布时间】:2020-11-04 14:09:01
【问题描述】:

我们有一个使用 Nginx 和 Gunicorn 反向代理设置在生产环境中提供服务的 Django 项目。除了一个小细节外,一切似乎都有效。不知何故,浏览器将以下地址“视为”不同的会话。

假设我使用example.com 地址登录该站点。 然后,如果我访问https://www.example.com,浏览器看不到用户已经登录。

当我访问 www.example.com 时,我在 Nginx 的浏览器中收到 404 错误。

我怀疑这与 Nginx 或 Gunicorn 的设置方式有关。任何有关如何解决此差异的帮助表示赞赏。

Nginx 配置

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
}

【问题讨论】:

  • 我想你想将http www 的流量重定向到https non-www
  • 也许吧。我该怎么做?
  • 我会发布我的答案..

标签: django nginx gunicorn


【解决方案1】:

重定向

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

https://example.com

您需要像这样在 nginx vhost 配置文件中进行更改:

# 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

}

这个帖子可能会帮助你https://www.digitalocean.com/community/questions/redirecting-https-www-domain-to-non-www-domain-with-nginx(我的回答是基于)

在你的settings.py:

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

# SESSION_COOKIE_SECURE = True
# CSRF_COOKIE_SECURE = True

更多详情见

【讨论】:

  • 谢谢。需要说明的是,前两个server 部分是我需要添加的,第三个是我现有的?
  • @MadPhysicist 我更新了我的答案,尝试备份旧配置并应用这个。我保留了所有内容,几乎没有重新排列,以使内容更加清晰易读。让我知道它是否有效。 BTW 查看这一行 proxy_pass http://127.0.0.1:8080; 和最后评论的 2 行 certbot 配置
  • 它似乎不起作用。这两个 URL 都不适用于此配置。
  • 尝试sudo nginx -t 测试配置,然后如果OK,请重新启动它,如果不是,您可以发布错误输出。
  • default_server 需要指令:listen 443 ssl default_server; # managed by Certbot
猜你喜欢
  • 2018-05-07
  • 2021-01-29
  • 2019-06-15
  • 1970-01-01
  • 2017-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
相关资源
最近更新 更多