Django @login_required删除https [英] Django @login_required dropping https

查看:103
本文介绍了Django @login_required删除https的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用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,然后与$ code> runserver 进行交谈。我的nginx配置是

 上游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;

#静态文件路径
root / home / gaurav / www / Cumulus / cumulus_lightbox / static;

location / {
proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for;
proxy_set_header主机$ http_host;
proxy_redirect关闭;

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;

#静态文件路径
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主机$ http_host;
proxy_redirect关闭;

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


解决方案

Django仅在代理服务器后面运行纯HTTP,所以它将始终使用它来构建绝对URL(例如重定向),除非您配置它是如何看到代理的请求最初是通过HTTPS进行的。 p>

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



但是,请注意文档中的安全警告:您必须确保代理可以从所有传入的客户端请求(HTTP和HTTPS)中替换或剥离受信任的标头。您的nginx配置不会与 X-Forwarded-Ssl 一样,使其成为可欺骗。



常规解决方案为了将 X转发协议设置为 http https 适用于您的每个代理配置。然后,您可以使用以下方式配置Django:

  SECURE_PROXY_SSL_HEADER =('HTTP_X_FORWARDED_PROTOCOL','https')


I'm trying to test my Django app locally using SSL. I have a view with the @login_required decorator. So when I hit /locker, I get redirected to /locker/login?next=/locker. This works fine with http.

However, whenever I use https, the redirect somehow drops the secure connection, so I get something like https://cumulus.dev/locker -> http://cumulus.dev/locker/login?next=/locker

If I go directly to https://cumulus.dev/locker/login?next=locker the page opens fine over a secure connection. But once I enter the username and password, I go back to http://cumulus.dev/locker.

I'm using Nginx to handle the SSL, which then talks to runserver. My nginx config is

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;
    }
}
}

解决方案

Django is running on plain HTTP only behind the proxy, so it will always use that to construct absolute URLs (such as redirects), unless you configure it how to see that the proxied request was originally made over HTTPS.

As of Django 1.4, you can do this using the SECURE_PROXY_SSL_HEADER setting. When Django sees the configured header, it will treat the request as HTTPS instead of HTTP: request.is_secure() will return true, https:// URLs will be generated, and so on.

However, note the security warnings in the documentation: you must ensure that the proxy replaces or strips the trusted header from all incoming client requests, both HTTP and HTTPS. Your nginx configuration above does not do that with X-Forwarded-Ssl, making it spoofable.

A conventional solution to this is to set X-Forwarded-Protocol to http or https, as appropriate, in each of your proxy configurations. Then, you can configure Django to look for it using:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')

这篇关于Django @login_required删除https的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆