Django SSL位于ELB,但使用Apache进行设置
现在我有一个支持SSL的网站。SSL处于ELB级别,因此apache http服务器从未看到它。我正试图让Apache强制所有请求都使用Django SSL位于ELB,但使用Apache进行设置,django,apache,ssl,amazon-web-services,Django,Apache,Ssl,Amazon Web Services,现在我有一个支持SSL的网站。SSL处于ELB级别,因此apache http服务器从未看到它。我正试图让Apache强制所有请求都使用https,这样就不会发出http请求。我正在阅读其他几篇文章,包括: 我可以为此使用ELB配置吗?或者我必须从ELB中删除私钥等,并将其全部放在web服务器级别?我找不到任何有关此的进一步信息…您可以在django级别处理此问题,这是我使用的: from django.http import HttpResponsePermanentRedirect f
https
,这样就不会发出http
请求。我正在阅读其他几篇文章,包括:
我可以为此使用ELB配置吗?或者我必须从ELB中删除私钥等,并将其全部放在web服务器级别?我找不到任何有关此的进一步信息…您可以在django级别处理此问题,这是我使用的:
from django.http import HttpResponsePermanentRedirect
from django.conf import settings
class SecureRequiredMiddleware(object):
def __init__(self):
self.paths = getattr(settings, 'SECURE_REQUIRED_PATHS')
self.enabled = self.paths and getattr(settings, 'HTTPS_SUPPORT')
def process_request(self, request):
if self.enabled and not request.is_secure():
full_path = request.get_full_path()
for path in self.paths:
if full_path.startswith(path):
secure_url = request.build_absolute_uri(full_path).replace(
'http://', 'https://')
return HttpResponsePermanentRedirect(secure_url)
将其添加到文件中,并使用中间件设置指向该文件。然后需要添加两个设置项。第一个被称为SECURE\u REQUIRED\u path
,它应该是URL的列表,如下所示:
SECURE_REQUIRED_PATHS = [
'/login', # require HTTPS for any URL starting with `/login`
'/account', # require HTTPS for any URL starting with `/account`
'/', # require HTTPS for all URLs
]
第二个应该是一个名为HTTPS\u SUPPORT
的标志:
HTTPS_SUPPORT = True
然后,每当用户使用HTTP访问您的
SECURE\u REQUIRED\u路径中的URL时,它们将被重定向到与HTTPS等效的路径。您可以通过在Apache配置中添加如下重写规则来强制HTTPS:
<VirtualHost *:80>
...
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=permanent]
...
</VirtualHost>
...
重新启动发动机
重写cond%{HTTP:X-Forwarded-Proto}!https
重写规则^.*$https://%{SERVER_NAME}%{REQUEST_URI}[L,R=permanent]
...
这里的关键是X-Forwarded-Proto
头。ELB处理https并将请求作为http转发给Apache,它还在过程中添加此头。重写规则检查此标头,以仅重定向非源自ELB的http请求。但这会在页面上创建https链接吗?或者它只是重定向每个请求?我不想这样做…它只会重定向发送到您的安全路径设置中的URL的请求。将证书放在应用程序节点而不是ELB上是一个非选项iirc,因为ELB需要能够解密SSL流,然后才能真正执行负载平衡。我理解这一点,但这不是正确的方法。正确的方法是另一种解决方案。。。因为它将重写http服务器上的URL。此代码将使其首先到达应用程序,然后它将重新运行每个请求(只要它在所需的https路径中)。这里的问题是什么,由于响应重写请求而导致性能损失?您可以调整中间件设置,使其首先激活,如果您的客户端正在缓存,它们将缓存永久重定向。我非常怀疑您是否会注意到这个中间件,事实上,在heroku上运行django应用程序时需要类似的东西,而无需自定义构建。