2011-12-08 18 views
47

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.¿Cómo hacer python en https de Heroku solamente?

¿Pero cuál es la mejor manera de deshabilitar el acceso http, o redirigir a https?

Respuesta

63

Combinando la respuesta de @CraigKerstiens y @allanlei en algo que he probado y verificado para que funcione. Heroku establece el HTTP_X_FORWARDED_PROTO a https cuando la solicitud es ssl, y podemos utilizar esto para comprobar:

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) 
+27

La respuesta es ahora una [aplicación en github] (https://github.com/rdegges/django-sslify) –

+1

Votación para poner github ... ¡Gracias! Justo lo que estaba buscando hoy. –

+3

Como nota al margen, esto no funciona si tiene DEBUG configurado en True. Pasé una hora pensando en eso, así que espero que esto le ahorre a alguien algo de tiempo. – Femi

6

¿Qué marco está utilizando para su aplicación? Si está utilizando Django se podía utilización sencilla algunos 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) 
+0

Sí, estoy usando django. Gracias por la respuesta: lo intentaré a menos que aparezca algo más simple (como una opción de heroku oculto). – Kristian

+0

Tuve que hacer un pequeño ajuste a tu respuesta, pero los moderadores rechazaron mi edición. He creado mi propia respuesta que soluciona el problema con redirecciones interminables en su respuesta actual.Gracias de todos modos, nunca habrías pensado en una solución de middleware sin tu contribución. – Kristian

+1

Esta solución crea un ciclo de redirección sin fin. Ver mi respuesta arriba .. – Kristian

13

No estoy seguro si la respuesta @ CraigKerstiens tiene en cuenta que request.is_secure() siempre devuelve False si detrás de proxy inverso de Heroku y no "fija". Si recuerdo correctamente, esto causará un bucle de redirección HTTP.

Si está ejecutando Django con gunicorn, otra manera de hacerlo es añadir lo siguiente al de gunicorn config

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

Ejecutar con un poco como esto en su Procfile

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

Mediante el establecimiento de gunicorn secure-scheme-header, request.is_secure() devolverá correctamente True en las solicitudes https. Ver Gunicorn Config.

Ahora el middleware de @ CraigKerstiens funcionará correctamente, incluidas las llamadas al 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.

+2

La configuración django SECURE_PROXY_SSL_HEADER ahora está disponible en la línea principal (ciertamente en 1.6, quizás antes). – Symmetric

4

Si está utilizando el frasco, esto funciona bastante bien:

1) No "PIP instalación flask- sslify"

(gitHub está aquí: https://github.com/kennethreitz/flask-sslify)

2) se incluyen 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) 
+0

Si hacemos esto ... ¿todavía tenemos que hacer las cosas de Heroku? lo siento un poco nuevo en este aspecto – John

+0

Aunque vea el problema "volteando" en https://github.com/kennethreitz/flask-sslify/issues/3 – wodow

33

Django 1.8 tendrá soporte de núcleo para no HTTPS redirect (integrado de django-secure):

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

Para que SECURE_SSL_REDIRECT para ser manipulados usted tiene que utilizar la SecurityMiddleware:

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

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

+0

¿Esto significa que el paquete pip sslify está obsoleto a partir de Django 1.8? – dfrankow

+0

@dfrankow django-sslify suena similar a django-secure, pero tendrá que confirmarlo con el autor del paquete – shangxiao

+0

@dfrankow No, aún necesita sslify con Django 1.8, si desea redirigir automáticamente a los usuarios de http a https . –

Cuestiones relacionadas