[Fixed]-DjangoRestFramework HTTPS Links With Routers and Viewsets

41👍

DRF reverse uses request.build_absolute_uri(url) to generate urls which will build URLs “using the server variables available in this request.”, so if the request is http, generated URLs will be HTTP and same thing for HTTPS.

If your django app running behind a reverse proxy, then you need to configure SECURE_PROXY_SSL_HEADER setting.

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

However, you have to be really careful when setting this:

Warning

You will probably open security holes in your site if you set this
without knowing what you’re doing. And if you fail to set it when you
should. Seriously.

Make sure ALL of the following are true before setting this (assuming
the values from the example above):

Your Django app is behind a proxy. Your proxy strips the
X-Forwarded-Proto header from all incoming requests. In other words,
if end users include that header in their requests, the proxy will
discard it. Your proxy sets the X-Forwarded-Proto header and sends it
to Django, but only for requests that originally come in via HTTPS. If
any of those are not true, you should keep this setting set to None
and find another way of determining HTTPS, perhaps via custom
middleware.

For nginx, you can set X-Forwarded-Proto header using this configuration:

location / {
    # ... 
    proxy_set_header X-Forwarded-Proto $scheme;
}

Leave a comment