build_absolute_uri with HTTPS behind reverse proxy

Viewed 3095

I'm serving my django app behind a reverse proxy

The internet -> Nginx -> Gunicorn socket -> Django app

In the nginx config:

upstream my_server {
  server unix:/webapps/my_app/run/gunicorn.sock fail_timeout=0;
}

The SSL is set up with certbot at the nginx level.

request.build_absolute_uri in views.py generates http links. How can I force it to generate https links?

3 Answers

By default Django ignore all X-Forwarded headers, base on Django docs.

Force read the X-Forwarded-Host header by setting USE_X_FORWARDED_HOST = True and set SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https'). So in settings.py:

USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

I use django behind apache2 so my solution was to put this on apache2

<VirtualHost *:443>
  RequestHeader set X-Forwarded-Proto 'https' env=HTTPS

After adding headers mod:

a2enmod headers

And this on django setting.py:

USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

With this all my build_absolute_uri started with https

Related