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

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

问题描述

我的原始问题是如何为Django启用HTTPS登录页面和唯一的回复,建议我将整个网站作为仅HTTPS使用。



鉴于我使用Django 1.3和nginx,使网站成为HTTPS的正确方法是什么?



一个回应提到了 a中间件解决方案,但有注意事项:


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


有关 nginx重写为https ,也提到POSTs丢失数据的问题,我不够熟悉nginx来确定解决方案的效果。



EFF的建议只允许HTTPS使用,请注意:



设置它时,应用程序必须设置Cookie上的Secure属性。此属性指示浏览器只通过安全(HTTPS)传输,不要保密(HTTP)发送cookie


像Django-auth这样的应用程序能否将Cookie设置为安全?或者我必须编写更多的中间件?



那么,配置Django / nginx的组合来实现HTTPS的最好方法是: / p>


  • 安全

  • 保存POST数据

  • 正确地

  • 与其他Django应用(例如Django-auth)的互动,正常工作

  • 我不知道的任何其他问题:)



修改 - 在测试多个浏览器时,我刚才发现的另一个问题。说我有一个URL https://mysite.com/search/ ,它有一个搜索表单/按钮。我点击按钮,像往常一样处理Django中的表单,并执行一个Django HttpResponseRedirect http://mysite.com/search?results=foo。根据需要,Nginx重定向到 https://mysite.com/search?results=foo



但是,当重定向发生时,Opera具有可见的 flash 。每个搜索都会发生,即使是相同的搜索字词(我猜https真的不缓存:)更糟糕的是,当我在IE中测试时,我首先得到消息:


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


之后点击是,紧接着是:


您即将通过安全连接查看页面 - 继续?


虽然第二个IE警告有一个选项可以关闭它 - 第一个警告没有,所以每次有人搜索并重定向到结果页面,他们至少会收到一条警告消息。

解决方案

对于John C的第二部分答案和Django 1.4 + ...



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



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

  SECURE_PROXY_SSL_HEADER =('HTTP_X_FORWARDED_PROTO','https')

然后,您需要Nginx在反向代理中设置自定义头。在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天全站免登陆