Django @login_required soltando https

9

Estou tentando testar meu aplicativo Django localmente usando SSL. Eu tenho uma visão com o decorador @login_required . Então, quando eu atingi /locker , fui redirecionado para /locker/login?next=/locker . Isso funciona bem com o http.

No entanto, sempre que eu uso https, o redirecionamento de alguma forma descarta a conexão segura, então eu recebo algo como https://cumulus.dev/locker -> http://cumulus.dev/locker/login?next=/locker

Se eu for diretamente para https://cumulus.dev/locker/login?next=locker , a página será aberta por uma conexão segura. Mas depois de inserir o nome de usuário e a senha, volto para http://cumulus.dev/locker .

Estou usando o Nginx para lidar com o SSL, que fala com runserver . Minha configuração 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;
    }
}
}
    
por Gaurav Dadhania 20.07.2012 в 03:23

1 resposta

4

O Django está rodando em HTTP simples apenas atrás do proxy, então ele sempre usará isso para construir URLs absolutas (como redirecionamentos), a menos que você configure como ver que a solicitação de proxy foi originalmente feita via HTTPS.

A partir do Django 1.4, você pode fazer isso usando o SECURE_PROXY_SSL_HEADER configuração. Quando o Django vê o cabeçalho configurado, ele tratará a solicitação como HTTPS em vez de HTTP: request.is_secure() retornará true, https:// URLs serão gerados e assim por diante.

No entanto, observe os avisos de segurança na documentação: você deve garantir que o proxy substitua ou elimine o cabeçalho confiável de todas as solicitações de entrada do cliente, HTTP e HTTPS. Sua configuração nginx acima não faz isso com X-Forwarded-Ssl , tornando-a spoofável.

Uma solução convencional para isso é definir X-Forwarded-Protocol para http ou https , conforme apropriado, em cada uma das suas configurações de proxy. Então, você pode configurar o Django para procurá-lo usando:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
    
por Pi Delport 20.07.2012 / 04:29