/ Backend

Django REST always return hyperlink with http proto even if the request is made via https

We always host Django app behind a proxy server(apache or nginx) in production, the connection from your client and the proxy server may be(better be) https. However, between the proxy server and Django app(gunicorn or whatever you're using) is usually http. So Django thinks that the client is using http, and returns all hyperlink including media link & hyperlink fields using http protocol.

Solution One

This sometimes is not a big problem, as we can force all http connection to our proxy server to use https like the following.

Redirect permanent / https://example.com/

This may solve the security problem but what if your client does not support http(IOS, WechatApp etc.)?

Solution Two(prefered)

The best way to solve this is to let Django know the protocol that your client is using.

As per Django's documentation, it uses request object's is_secure() method to determine if the caller is using https. Since the headers are stripped by our proxy server, is_secure() will always return False resulting in http appears in hyperlinks.

Now we know the reason behind this, solving the problem becomes trivial.

Use one of Django's setting

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

this means that if the request has a header X_FORWARDED_PROTO with value https, Django considers it to be secure and will use https in hyperlinks.

And don't forget to forward protocol in your proxy server, here is an example in Apache.

RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}

Problem solved :)

mimimi

mimimi

Currently a Computer Engineering student at the National University of Singapore, passionate about software engineering. Contact me: info at mimimi.fun

Read More
Django REST always return hyperlink with http proto even if the request is made via https
Share this