herokuapp - heroku web python
¿Cómo hacer python en https de Heroku solamente? (5)
Tengo la aplicación python / django en Heroku (pila Cedar) y me gustaría hacerla accesible solo a través de https. He habilitado la opción "ssl piggyback" y puedo conectarme a ella a través de https.
Pero, ¿cuál es la mejor manera de deshabilitar el acceso http, o redirigir a https?
¿Qué marco estás usando para tu aplicación? Si está usando Django, podría usar un middleware similar a:
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)
Combinando la respuesta de @CraigKerstiens y @allanlei en algo que he probado y verificado para que funcione. Heroku establece HTTP_X_FORWARDED_PROTO en https cuando request es ssl, y podemos usar esto para verificar:
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 tendrá soporte básico para el redireccionamiento no HTTPS (integrado desde django-secure ):
SECURE_SSL_REDIRECT = True # [1]
SECURE_PROXY_SSL_HEADER = (''HTTP_X_FORWARDED_PROTO'', ''https'')
Para que se SECURE_SSL_REDIRECT
debe usar SecurityMiddleware
:
MIDDLEWARE = [
...
''django.middleware.security.SecurityMiddleware'',
]
[1] https://docs.djangoproject.com/en/1.8/ref/settings/#secure-ssl-redirect
No estoy seguro si la respuesta de @ CraigKerstiens tiene en cuenta que request.is_secure()
siempre devuelve False
si está detrás del proxy inverso de Heroku y no es "fixed". Si recuerdo correctamente, esto causará un bucle de redirección HTTP.
Si está ejecutando Django con gunicornio, otra forma de hacerlo es agregar lo siguiente a las configuraciones de gunicornio
secure_scheme_headers = {
''X-FORWARDED-PROTO'': ''https''
}
Ejecutar con algunos como este en su Procfile
web: python manage.py run_gunicorn -b 0.0.0.0:$PORT -c config/gunicorn.conf
Al establecer el encabezado de secure-scheme-header
de gunicorn, request.is_secure()
devolverá True
en las solicitudes de https. Vea la configuración de Gunicorn .
Ahora el middleware de @ CraigKerstiens funcionará correctamente, incluidas las llamadas a request.is_secure()
en su aplicación.
Nota: Django también tiene la misma configuración de configuración llamada SECURE_PROXY_SSL_HEADER
, pero está en la versión dev.
Si usas Flask, esto funciona bastante bien:
1) Haz "pip install flask-sslify"
(github está aquí: https://github.com/kennethreitz/flask-sslify )
2) Incluye las siguientes líneas:
from flask_sslify import SSLify
if ''DYNO'' in os.environ: # only trigger SSLify if the app is running on Heroku
sslify = SSLify(app)