J'ai une application python/Django sur Heroku (pile Cedar) et je voudrais la rendre accessible via https uniquement. J'ai activé l'option "ssl piggyback" et je peux me connecter via https.
Mais quelle est la meilleure façon de désactiver l'accès http ou de rediriger vers https?
Combiner la réponse de @CraigKerstiens et @allanlei en quelque chose que j'ai testé et vérifié pour fonctionner. Heroku définit HTTP_X_FORWARDED_PROTO sur https lorsque la demande est SSL, et nous pouvons l'utiliser pour vérifier:
from Django.conf import settings
from Django.http import HttpResponseRedirect
class 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 aura un support de base pour la redirection non HTTPS (intégré à partir de Django-secure ):
SECURE_SSL_REDIRECT = True # [1]
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
Pour SECURE_SSL_REDIRECT
pour être manipulé, vous devez utiliser le SecurityMiddleware
:
MIDDLEWARE = [
...
'Django.middleware.security.SecurityMiddleware',
]
[1] https://docs.djangoproject.com/en/1.8/ref/settings/#secure-ssl-redirect
Je ne sais pas si la réponse de @ CraigKerstiens tient compte du fait que request.is_secure()
renvoie toujours False
si derrière le proxy inverse de Heroku et non "fixe". Si je me souviens bien, cela provoquera une boucle de redirection HTTP.
Si vous exécutez Django avec gunicorn, une autre façon de le faire est d'ajouter ce qui suit à la configuration de gunicorn
secure_scheme_headers = {
'X-FORWARDED-PROTO': 'https'
}
Exécuter avec certains comme celui-ci dans votre Procfile
web: python manage.py run_gunicorn -b 0.0.0.0:$PORT -c config/gunicorn.conf
En définissant le secure-scheme-header
De gunicorn, request.is_secure()
renverra correctement True
sur les requêtes https. Voir Gunicorn Config .
Le middleware de @ CraigKerstiens fonctionnera désormais correctement, y compris tous les appels à request.is_secure()
dans votre application.
Remarque: Django a également le même appel de paramètre de configuration SECURE_PROXY_SSL_HEADER
, Mais dans la version de développement.
Quel cadre utilisez-vous pour votre application? Si vous utilisez Django vous pouvez simplement utiliser un middleware similaire à:
import re
from Django.conf import settings
from Django.core import urlresolvers
from Django.http import HttpResponse, HttpResponseRedirect
class SSLMiddleware(object):
def process_request(self, request):
if not any([settings.DEBUG, request.is_secure()]):
url = request.build_absolute_uri(request.get_full_path())
secure_url = url.replace("http://", "https://")
return HttpResponseRedirect(secure_url)
Si vous utilisez Flask, cela fonctionne très bien:
1) Faites "pip install flask-sslify"
(github est ici: https://github.com/kennethreitz/flask-sslify )
2) Incluez les lignes suivantes:
from flask_sslify import SSLify
if 'DYNO' in os.environ: # only trigger SSLify if the app is running on Heroku
sslify = SSLify(app)