build_absolute_uri with HTTPS behind reverse proxy
Asked Answered
I

3

20

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?

Illuminate answered 27/5, 2020 at 15:52 Comment(1)
I just spent several hours to find out that I have this same question. request.build_absolute_uri sounds so strongly like it would solve this problem that it took me long to recognize it may not.Caricature
A
38

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')
Accolade answered 28/1, 2021 at 9:19 Comment(2)
Thanks for explanation. For anyone wanting a more detailed explanation of how nginx works with django and how to make sure nginx conf is set correctly to use these settings, then I recommend to check this article: mattsegal.dev/nginx-django-reverse-proxy-config.htmlRetake
Instead of HTTP_X_FORWARDED_PROTO the HTTP_X_FORWARDED_SCHEME worked better in our AKS environment.Icono
R
2

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

Ridgway answered 9/7, 2021 at 3:1 Comment(0)
N
-1

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.

Newsstand answered 27/5, 2020 at 16:51 Comment(1)
My web server already redirects. This does not solve the problem that build_absolute_uri generates HTTP linksIlluminate

© 2022 - 2024 — McMap. All rights reserved.