12

I am using Django on DotCloud which uses Django on top of uwsgi + nginx. I am trying to redirect all http traffic to https which is leading to a redirect loop. I am using the following http configuration

if ($http_x_forwarded_port != 443) { rewrite ^ https://$http_host/; }

It seems that Django doesn't understand that it is operating on https and the header is not preserved. It redirects https://url.com/ to http://url.com/accounts/login/ which is redirecting again and again leading to a redirect loop. I am not really an expert in nginx and do not understand it well enough. What can I be doing wrong?

In short how do I run redirect http to https in django running on top of uswsgi and nginx.

raacer
  • 5,302
  • 3
  • 27
  • 46
Rewolverine
  • 375
  • 1
  • 3
  • 8
  • 3
    try reading through this - http://yuji.wordpress.com/2008/08/15/django-nginx-making-ssl-work-on-django-behind-a-reverse-proxy/ – Vidyanand Jul 21 '11 at 23:09

3 Answers3

14

I needed a bit more to make Django aware that it should be using https.

In settings.py I added SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

And in the nginx configuration

location / {
    proxy_set_header X-Forwarded-Proto https;
    include uwsgi_params;
    uwsgi_param UWSGI_SCHEME https;
    uwsgi_pass_header X_FORWARDED_PROTO;
    uwsgi_pass unix:///path/to/socket;
}
sellonen
  • 181
  • 1
  • 5
  • For the sake of posterity, this answer works when only port 443 is open (ie. firewall blocks request on port 80) – fmorency Dec 21 '13 at 00:31
  • uwsgi_pass_header allows to pass header from server to client, so this is probably not what you need here. What about correct redirects, the UWSGI_SCHEME param did the trick in my case without any custom headers. Is the SECURE_PROXY_SSL_HEADER setting really needed? – raacer Oct 25 '15 at 23:36
7
server {
  listen  80;
  server_name  yourhttphost;
  rewrite ^ https://yourhttpshost$request_uri? permanent; #301 redirect
}
server {
  listen 443;
  server_name  yourhttpshost;
  ........
  the rest
  ........
}

Using "if" in nginx config is a very bad idea!

MechanisM
  • 906
  • 8
  • 14
3
if ( $scheme = "http" ) {
     rewrite ^/(.*)$   https://$host/ permanent;
}
doomatel
  • 607
  • 1
  • 6
  • 8
  • 2
    Having an "if" processed for each request is very ineffective in Nginx. It's better to create a separate :80 server and redirect every request hitting it. – kravietz Dec 10 '15 at 22:55