Saturnix
Saturnix

Reputation: 10564

build_absolute_uri with HTTPS behind reverse proxy

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?

Upvotes: 22

Views: 9258

Answers (3)

Ali ZahediGol
Ali ZahediGol

Reputation: 1096

By default Django ignores 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')

Upvotes: 41

user3486626
user3486626

Reputation: 166

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

Upvotes: 2

Alex
Alex

Reputation: 58

There's a note in the django documentation here https://docs.djangoproject.com/en/3.0/ref/request-response/#django.http.HttpRequest.build_absolute_uri:

Mixing HTTP and HTTPS on the same site is discouraged, therefore build_absolute_uri() will always generate an absolute URI with the same scheme the current request has. If you need to redirect users to HTTPS, it’s best to let your Web server redirect all HTTP traffic to HTTPS.

Upvotes: -2

Related Questions