Django 的 HttpResponseRedirect 是 http 而不是 https

Posted

技术标签:

【中文标题】Django 的 HttpResponseRedirect 是 http 而不是 https【英文标题】:Django's HttpResponseRedirect is http instead of https 【发布时间】:2017-05-19 21:07:35 【问题描述】:

我的服务器运行 Django + Gunicorn + nginx

我已添加 SSL 证书并配置 nginx 以将 http 重定向到 https。当收到 https 请求时,nginx 会将其作为 http 传递给 Gunicorn。

我的程序有时会返回HttpResponseRedirect,浏览器收到重定向响应并重新请求为http,所以nginx重定向到https。

我怎样才能避免这种情况?如何配置服务器以使第一个重定向直接指向 https URL?

【问题讨论】:

其实我也做同样的事情。告诉 Nginx 将所有 http 请求重定向到 https,它工作得很好。 【参考方案1】:

在 nginx 配置中(location 块内),指定:

proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_redirect 告诉 nginx,如果后端返回 HTTP 重定向,它应该保持原样。默认情况下,nginx 假设后端是愚蠢的,并试图变得聪明;如果后端返回一个 HTTP 重定向,上面写着“重定向到http://localhost:8000/somewhere”,nginx 会用类似于http://yourowndomain.com/somewhere 的内容替换它。但是 Django 并不愚蠢(或者它可以配置为不愚蠢)。

Django 不知道请求是通过 HTTPS 还是纯 HTTP 发出的; nginx 知道这一点,但它随后向 Django 后端发出的请求始终是纯 HTTP。我们告诉 nginx 使用 X-Forwarded-Proto HTTP 标头传递此信息,以便相关的 Django 功能(例如 request.is_secure())正常工作。您还需要在settings.py 中设置SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

【讨论】:

我需要同时设置 nginx 和 django 还是只设置 nginx? 我不确定你的意思。您最好的选择是将 django 返回重定向作为相对 url,即“/target”而不是“domain/target”。 我的意思是在我按照你说的那样设置了nginx之后,我是否还需要设置django settings.py或者它只是对其他功能的改进。毕竟,你的回答真的很有帮助,谢谢! @permike 我认为这可能对更多人有用,所以我在djangodeployment.com/2017/01/24/… 写了博客。

以上是关于Django 的 HttpResponseRedirect 是 http 而不是 https的主要内容,如果未能解决你的问题,请参考以下文章

Django系列

django的文档

Django 大神带你飞系列~走进Django

Django:启动django

django的单元测试怎么用

django-admin 和django-admin.py的区别