9

我正在尝试使用 SSL 在本地测试我的 Django 应用程序。我和@login_required装饰师有意见。所以当我点击时/locker,我被重定向到/locker/login?next=/locker. 这适用于 http。

但是,每当我使用 https 时,重定向都会以某种方式断开安全连接,所以我得到类似https://cumulus.dev/locker -> http://cumulus.dev/locker/login?next=/locker

如果我直接进入https://cumulus.dev/locker/login?next=locker该页面,则可以通过安全连接正常打开。但是一旦我输入用户名和密码,我就会回到http://cumulus.dev/locker.

我正在使用 Nginx 处理 SSL,然后与runserver. 我的 nginx 配置是

upstream app_server_djangoapp {
server localhost:8000 fail_timeout=0;
}

server {
listen 80;
server_name cumulus.dev;

access_log  /var/log/nginx/cumulus-dev-access.log;
error_log  /var/log/nginx/cumulus-dev-error.log info;

keepalive_timeout 5;

# path for static files
root /home/gaurav/www/Cumulus/cumulus_lightbox/static;

location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    if (!-f $request_filename) {
        proxy_pass http://app_server_djangoapp;
        break;
    }
}
}

server {
listen 443;
server_name cumulus.dev;

ssl on;
ssl_certificate /etc/ssl/cacert-cumulus.pem;
ssl_certificate_key /etc/ssl/privkey.pem;

access_log  /var/log/nginx/cumulus-dev-access.log;
error_log  /var/log/nginx/cumulus-dev-error.log info;

keepalive_timeout 5;

# path for static files
root /home/gaurav/www/Cumulus/cumulus_lightbox/static;

location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Ssl on;
    proxy_set_header Host $http_host;
    proxy_redirect off;

    if (!-f $request_filename) {
        proxy_pass http://app_server_djangoapp;
        break;
    }
}
}
4

1 回答 1

4

Django 仅在代理后面在纯 HTTP 上运行,因此它将始终使用它来构造绝对 URL(例如重定向),除非您配置它如何查看代理请求最初是通过 HTTPS 发出的。

从 Django 1.4 开始,您可以使用SECURE_PROXY_SSL_HEADER设置来执行此操作。当 Django 看到配置的 header 时,它会将请求视为 HTTPS 而不是 HTTP:request.is_secure()将返回 true,https://将生成 URL,等等。

但是,请注意文档中的安全警告:您必须确保代理从所有传入的客户端请求(HTTP 和 HTTPS)中替换或删除受信任的标头。您上面的 nginx 配置不使用X-Forwarded-Ssl,使其具有欺骗性。

对此的常规解决方案是在您的每个代理配置中根据需要设置X-Forwarded-Protocolhttp或。https然后,您可以配置 Django 以使用以下方法查找它:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
于 2012-07-20T02:29:10.883 回答