Reputation: 10564
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
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
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
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