我在亚马逊上托管的网站拥有ELB级别的SSL认证。我使用以下站点设置了一个中间件,将所有http
请求转发给https
:
http://djangosnippets.org/snippets/2472/
它工作得很好。但这是我的问题。每个请求都被转发,所以我注意到单击链接等时略有延迟。 没什么极端的。但是有没有办法强迫 django 通过 https
做所有事情?当我有代码要HttpResponse
和HttpResponseRedirect
时,如何让它默认为 https
而不是 http
?我试图搜索这个但没有成功...
我知道如果我为每个 URL 键入 https://www...
进行重定向并在页面链接上键入是可能的,但我想尽可能避免这样做。
查看您发布的中间件,它正在执行您提到的您不想手动执行的操作,即将https
附加到来自您的域的每个传入http
请求中。我建议您将此作业卸载到前端服务器(nginx或apache)。
示例与
-
恩金克斯
-
阿帕奇
当 Django 构建要重定向到的绝对 URI 时,它会检查request.is_secure以决定它应该使用哪种协议方案(http、https 或 ftp)。
Django 默认根据用于请求的协议执行此操作,但正如您所确定的,当在 LB 或代理后面时,由于 LB/代理级别的 SSL 终止,这可能是错误的。
你可以配置 Django 来检测这个确切的情况,使用 SECURE_PROXY_SSL_HEADER 设置。
我们目前使用 Nginx 来平衡负载,对请求强制执行 SSL,并在 SSL 连接代理到内部应用服务器时终止它们。它没有那么花哨的负载平衡功能,但Nginx足够小,速度足够快,可以放在任何地方。
以下是您可能需要的代码位:
# listen on port 80 and redirect to SSL.
server {
listen 80;
server_name site.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
# listen on port 443, terminate SSL, and proxy to internal web app
# can be node, rails, whatever.
server {
listen 443;
server_name site.com;
gzip on;
client_max_body_size 250M;
ssl on;
ssl_certificate /etc/nginx/site.com.crt;
ssl_certificate_key /etc/nginx/site.com.key;
keepalive_timeout 70;
location / {
proxy_pass http://127.0.0.1:8080;
# We add this extra header just so proxied web app
# knows this used to be an SSL connection.
proxy_set_header x-https 1;
include /etc/nginx/conf.d/proxy.conf;
}
}