How to make python on Heroku https only? How to make python on Heroku https only? python python

How to make python on Heroku https only?


Combining the answer from @CraigKerstiens and @allanlei into something I have tested, and verified to work. Heroku sets the HTTP_X_FORWARDED_PROTO to https when request is ssl, and we can use this to check:

from django.conf import settingsfrom django.http import HttpResponseRedirectclass SSLMiddleware(object):    def process_request(self, request):        if not any([settings.DEBUG, request.is_secure(), request.META.get("HTTP_X_FORWARDED_PROTO", "") == 'https']):            url = request.build_absolute_uri(request.get_full_path())            secure_url = url.replace("http://", "https://")            return HttpResponseRedirect(secure_url)


Django 1.8 will have core support for non-HTTPS redirect (integrated from django-secure):

SECURE_SSL_REDIRECT = True # [1]SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

In order for SECURE_SSL_REDIRECT to be handled you have to use the SecurityMiddleware:

MIDDLEWARE = [    ...    'django.middleware.security.SecurityMiddleware',]

[1] https://docs.djangoproject.com/en/1.8/ref/settings/#secure-ssl-redirect


Not sure if @CraigKerstiens's answer takes into account that request.is_secure() always returns False if behind Heroku's reverse proxy and not "fixed". If I remember correctly, this will cause a HTTP redirect loop.

If you are running Django with gunicorn, another way to do it is to add the following to gunicorn's config

secure_scheme_headers = {    'X-FORWARDED-PROTO': 'https'}

Run with some like this in your Procfile

web: python manage.py run_gunicorn -b 0.0.0.0:$PORT -c config/gunicorn.conf

By setting gunicorn's secure-scheme-header, request.is_secure() will properly return True on https requests. See Gunicorn Config.

Now @CraigKerstiens's middleware will work properly, including any calls to request.is_secure() in your app.

Note: Django also has the same config setting call SECURE_PROXY_SSL_HEADER, buts in the dev version.