如何使用 Django/nginx 部署仅支持 HTTPS 的站点? [英] How to deploy an HTTPS-only site, with Django/nginx?

查看:18
本文介绍了如何使用 Django/nginx 部署仅支持 HTTPS 的站点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最初的问题是如何为 Django 启用 HTTPS登录页面,也是唯一的回应,建议我 - 将整个网站设为仅限 HTTPS.

鉴于我使用的是 Django 1.3 和 nginx,使站点仅支持 HTTPS 的正确方法是什么?

一个回复提到了一个中间件解决方案,但有一个警告:

<块引用>

Django 无法在维护 POST 数据的同时执行 SSL 重定向.请构建您的视图,以便重定向仅在 GET 期间发生.

关于nginx 重写为 https,还提到了 POST 丢失数据的问题,我对 nginx 不够熟悉,无法确定解决方案的效果如何.

并且EFF 建议仅使用 HTTPS,并指出:><块引用>

应用程序必须在 cookie 上设置 Secure 属性,当设置它.该属性指示浏览器发送 cookie仅通过安全 (HTTPS) 传输,绝不会不安全 (HTTP).

像 Django-auth 这样的应用程序是否能够将 cookie 设置为安全?还是我必须写更多的中间件?

那么,配置 Django/nginx 的组合来实现 HTTPS-only 的最佳方式是什么,就以下方面而言:

  • 安全
  • 保存 POST 数据
  • cookies 处理得当
  • 与其他 Django 应用程序(例如 Django-auth)的交互工作正常
  • 我不知道的任何其他问题:)

编辑 - 我刚刚在测试多个浏览器时发现的另一个问题.假设我有 URL https://mysite.com/search/,它有一个搜索表单/按钮.我单击按钮,像往常一样在 Django 中处理表单,然后执行 Django HttpResponseRedirecthttp://mysite.com/search?results="foo".Nginx 根据需要将其重定向到 https://mysite.com/search?results="foo".

然而 - 当重定向发生时,Opera 有一个可见的flash.它发生在每次搜索中,即使是相同的搜索词(我猜 https 真的不缓存:) 更糟糕的是,当我在 IE 中测试它时,我首先收到消息:

<块引用>

您将被重定向到不安全的连接 - 继续吗?

点击是"后,紧接着是:

<块引用>

您要通过安全连接查看页面 - 继续吗?

虽然第二个 IE 警告可以选择关闭它 - 第一个警告没有,所以每次有人进行搜索并被重定向到结果页面时,他们至少会收到一个警告留言.

解决方案

对于 John C 的回答的第二部分,以及 Django 1.4+...

您可以将 request.scheme 更改为 https,而不是扩展 HttpResponseRedirect.因为 Django 在 Nginx 的反向代理后面,它不知道原始请求是安全的.

在您的 Django 设置中,设置 SECURE_PROXY_SSL_HEADER 设置:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

然后,需要Nginx在反向代理中设置自定义header.在 Nginx 站点设置中:

location/{# ...proxy_set_header X-Forwarded-Proto $scheme;}

这样 request.scheme == 'https'request.is_secure() 返回 True.request.build_absolute_uri() 返回 https://... 等等...

My original question was how to enable HTTPS for a Django login page, and the only response, recommended that I - make the entire site as HTTPS-only.

Given that I'm using Django 1.3 and nginx, what's the correct way to make a site HTTPS-only?

The one response mentioned a middleware solution, but had the caveat:

Django can't perform a SSL redirect while maintaining POST data. Please structure your views so that redirects only occur during GETs.

A question on Server Fault about nginx rewriting to https, also mentioned problems with POSTs losing data, and I'm not familiar enough with nginx to determine how well the solution works.

And EFF's recommendation to go HTTPS-only, notes that:

The application must set the Secure attribute on the cookie when setting it. This attribute instructs the browser to send the cookie only over secure (HTTPS) transport, never insecure (HTTP).

Do apps like Django-auth have the ability to set cookies as Secure? Or do I have to write more middleware?

So, what is the best way to configure the combination of Django/nginx to implement HTTPS-only, in terms of:

  • security
  • preservation of POST data
  • cookies handled properly
  • interaction with other Django apps (such as Django-auth), works properly
  • any other issues I'm not aware of :)

Edit - another issue I just discovered, while testing multiple browsers. Say I have the URL https://mysite.com/search/, which has a search form/button. I click the button, process the form in Django as usual, and do a Django HttpResponseRedirect to http://mysite.com/search?results="foo". Nginx redirects that to https://mysite.com/search?results="foo", as desired.

However - Opera has a visible flash when the redirection happens. And it happens every search, even for the same search term (I guess https really doesn't cache :) Worse, when I test it in IE, I first get the message:

You are about to be redirected to a connection that is not secure - continue?

After clicking "yes", this is immediately followed by:

You are about to view pages over a secure connection - continue?

Although the second IE warning has an option to turn it off - the first warning does not, so every time someone does a search and gets redirected to a results page, they get at least one warning message.

解决方案

For the 2nd part of John C's answer, and Django 1.4+...

Instead of extending HttpResponseRedirect, you can change the request.scheme to https. Because Django is behind Nginx's reverse proxy, it doesn't know the original request was secure.

In your Django settings, set the SECURE_PROXY_SSL_HEADER setting:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

Then, you need Nginx to set the custom header in the reverse proxy. In the Nginx site settings:

location / {
    # ... 
    proxy_set_header X-Forwarded-Proto $scheme;
}

This way request.scheme == 'https' and request.is_secure() returns True. request.build_absolute_uri() returns https://... and so on...

这篇关于如何使用 Django/nginx 部署仅支持 HTTPS 的站点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆