Django SSL位于ELB,但使用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

现在我有一个支持SSL的网站。SSL处于ELB级别,因此apache http服务器从未看到它。我正试图让Apache强制所有请求都使用
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应用程序时需要类似的东西,而无需自定义构建。