[英]Django: redirect http to https safely for Heroku app
I am trying to redirect my Django + Heroku app from http
to https
, but I am surprised that I did not find any safe and straightforward way.我试图将我的 Django + Heroku 应用程序从
http
重定向到https
,但我很惊讶我没有找到任何安全和直接的方法。
According to Heroku : 根据 Heroku 的说法:
Issue
问题
You have configured an SSL endpoint and now you want your application to use https for all requests.
您已经配置了一个 SSL 端点,现在您希望您的应用程序对所有请求使用 https。
Resolution
分辨率
Redirects need to be performed at the application level as the Heroku router does not provide this functionality.
重定向需要在应用程序级别执行,因为 Heroku 路由器不提供此功能。 You should code the redirect logic into your application.
您应该将重定向逻辑编码到您的应用程序中。
Under the hood, Heroku router (over)writes the X-Forwarded-Proto and the X-Forwarded-Port request headers.
在幕后,Heroku 路由器(覆盖)写入 X-Forwarded-Proto 和 X-Forwarded-Port 请求标头。 The app checks X-Forwarded-Proto and respond with a redirect response when it is not https but http.
该应用程序检查 X-Forwarded-Proto 并在它不是 https 而是 http 时使用重定向响应进行响应。
...
...
Django
姜戈
Set
SECURE_SSL_REDIRECT
toTrue
.将
SECURE_SSL_REDIRECT
设置为True
。
So it must be done at Django.所以必须在Django完成。 This is the most complete answer I found, and this one is also similar.
这是我找到的最完整的答案,这个也是类似的。
Django 1.8 will have core support for non-HTTPS redirect (integrated from django-secure ):
Django 1.8 将为非 HTTPS 重定向提供核心支持(从django-secure集成):
SECURE_SSL_REDIRECT = True SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
In order for
SECURE_SSL_REDIRECT
to be handled you have to use theSecurityMiddleware
:为了处理
SECURE_SSL_REDIRECT
,您必须使用SecurityMiddleware
:MIDDLEWARE = [ ... 'django.middleware.security.SecurityMiddleware', ]
Note that both use请注意,两者都使用
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
It seems that without this setting, it is not working on Heroku.似乎没有这个设置,它在 Heroku 上不起作用。 And now comes the interesting/scary part.
现在是有趣/可怕的部分。 As explained in the docs :
如文档中所述:
SECURE_SSL_REDIRECT
SECURE_SSL_REDIRECT
...
...
If turning this to True causes infinite redirects, it probably means your site is running behind a proxy and can't tell which requests are secure and which are not.
如果将此设置为 True 会导致无限重定向,则可能意味着您的站点在代理后面运行,并且无法分辨哪些请求是安全的,哪些不是。 Your proxy likely sets a header to indicate secure requests;
您的代理可能会设置一个标头来指示安全请求; you can correct the problem by finding out what that header is and configuring the
SECURE_PROXY_SSL_HEADER
setting accordingly.您可以通过找出该标头是什么并相应地配置
SECURE_PROXY_SSL_HEADER
设置来纠正问题。
Then, checking about SECURE_PROXY_SSL_HEADER
:然后,检查
SECURE_PROXY_SSL_HEADER
:
Warning
警告
You will probably open security holes in your site if you set this without knowing what you're doing.
如果您在不知道自己在做什么的情况下进行设置,您可能会在您的站点中打开安全漏洞。 And if you fail to set it when you should.
如果你没有在你应该设置的时候设置它。 Seriously.
认真的。
Which makes me want to find a safer solution... In this other question it says it should be fine , but I don't find it convincing enough to ignore such a warning.这让我想找到一个更安全的解决方案......在另一个问题中它说它应该没问题,但我认为它不足以令人信服地忽略这样的警告。
Has Django really not any other solution that is safe to implement? Django 真的没有任何其他可以安全实施的解决方案吗?
I am using version 1.11我使用的是 1.11 版
Update:更新:
I found the django-sslify package , but it also requires setting SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
, so I guess it doesn't make a difference in terms of potential security holes.我找到了django-sslify 包,但它也需要设置
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
,所以我想它在潜在安全漏洞方面没有区别。 Please, correct me if this assumption is wrong.如果这个假设是错误的,请纠正我。
I'm late to this party, but I think the key here is to simply understand what you are doing.我参加这个聚会迟到了,但我认为这里的关键是简单地了解你在做什么。 I hope I understand what I am doing, but honestly am not 100% sure.
我希望我明白我在做什么,但老实说我不是 100% 确定。 I think HTTP_X_FORWARDED_PROTO is dangerous if you use it blindly because it makes Django think you are receiving an HTTPS request (even if HTTP_X_FORWARDED_PROTO is, in fact, spoofed).
我认为 HTTP_X_FORWARDED_PROTO 如果你盲目使用它是危险的,因为它让 Django 认为你正在接收 HTTPS 请求(即使 HTTP_X_FORWARDED_PROTO 实际上是欺骗的)。
But, if you are behind a properly functioning load balance/proxy (like AWS) then you can be confident that HTTP_X_FORWARDED_PROTO is being set correctly.但是,如果您支持正常运行的负载平衡/代理(如 AWS),那么您可以确信 HTTP_X_FORWARDED_PROTO 设置正确。 In this case, HTTP_X_FORWARDED_PROTO serves to tell Django that it's fine, don't worry about it (because you are trusting the proxy to not allow through a spoofed header), and stop trying to continuously redirect to SSL.
在这种情况下, HTTP_X_FORWARDED_PROTO 用于告诉 Django 没问题,不要担心(因为您相信代理不允许通过欺骗头),并停止尝试不断重定向到 SSL。
Finally, HTTP_X_FORWARDED_PROTO behind a proxy/load balancer is necessary even if you aren't using SECURE_SSL_REDIRECT = True (eg if the redirection is happening in a properly configured web server before getting to Django), because it also affects the is_secure() function on the request, which would always be false if your proxy is swallowing the original request (eg it's common to go from HTTPS between the client and your proxy/load balancer to HTTP between your proxy/load balancer and a web server).最后,即使您没有使用 SECURE_SSL_REDIRECT = True(例如,如果在访问 Django 之前在正确配置的 Web 服务器中发生重定向),代理/负载平衡器后面的 HTTP_X_FORWARDED_PROTO 也是必要的,因为它也会影响 is_secure() 函数请求,如果您的代理正在吞下原始请求(例如,从客户端和您的代理/负载均衡器之间的 HTTPS 到您的代理/负载均衡器和 Web 服务器之间的 HTTP,这是很常见的)。
Source: https://docs.djangoproject.com/en/3.0/ref/settings/#std:setting-SECURE_PROXY_SSL_HEADER but I had to read it multiple time to put this all together in my head.来源: https : //docs.djangoproject.com/en/3.0/ref/settings/#std : setting-SECURE_PROXY_SSL_HEADER但我不得不多次阅读它才能将所有这些放在我的脑海中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.