I was deploying my first Django application today on a production server. Nginx is the proxy server and gunicorn is the WSGI web server. Supervisor is being used to ensure the gunicorn workers are always re-spawned if they die. The firewall is setup to only allow HTTPS connections. After a lot of tweaking the settings, I was finally able to see my page over the public internet.

An interesting thing was happening when I was trying to get to the admin. I would use access the admin over HTTPS and login. However I was being redirected to HTTP after the login and I would never see a page as the firewall would block the request. But when I reload the admin page using HTTPS I can see that I was logged in. So basically I needed to figure out what to do so Django admin would be served over HTTPS after login.

After some snooping around on the net, I find the answer on stackoverflow.

Adding the following to nginx.conf:

location / {
    ...
    include                 uwsgi_params;
    uwsgi_param             HTTP_X_FORWARDED_PROTOCOL https;
    uwsgi_param             UWSGI_SCHEME   $scheme;
    proxy_set_header        X-Forwarded-Protocol $scheme;
}

Add the following to settings.py:

SESSION_COOKIE_SECURE = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
CSRF_COOKIE_SECURE = True