We recently upgraded one of our e-commerce websites to Django 1.4 and were
pleased to find the new
Our server is using nginx to proxy requests to Apache which serves the Django
project. Therefore, Apache/Django is not aware of when incoming requests are
HttpRequest.is_secure() will always return
False. That means
any decorators or middleware which redirect a view to a secure URL will result
in an infinite redirect loop.
The solution is:
Have the proxy server (nginx in our case) set the
X-Forwarded-ProtocolHTTP header. In the nginx config:
proxy_set_header X-Forwarded-Protocol $scheme;
Tell Django to use the
X-Forwarded-ProtocolHTTP header to determine if the request is secure. We define
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
The way that works is nginx will set
X-Forwarded-Protocol to "http" on normal
connections and "https" on secure connections. Django's
method will return
True when it's set to "https".
Make sure you read the security warning for
SECURE_PROXY_SSL_HEADER if you're goingn to use it.