Как сделать python только на https Heroku?

У меня есть приложение python/django на Heroku (Cedar stack) и вы хотите сделать его доступным только через https. Я включил "ssl piggyback" -option и могу подключиться к нему через https.

Но каков наилучший способ отключить доступ к http или перенаправить на https?

Ответ 1

Объединяя ответ от @CraigKerstiens и @allanlei во что-то, что я тестировал, и проверено на работу. Heroku устанавливает HTTP_X_FORWARDED_PROTO в https, когда запрос ssl, и мы можем использовать это для проверки:

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)

Ответ 2

Django 1.8 будет иметь основную поддержку для перенаправления без HTTPS (интегрирован из django-secure):

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

Чтобы обрабатывать SECURE_SSL_REDIRECT, вы должны использовать SecurityMiddleware:

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

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

Ответ 3

Не уверен, что ответ @CraigKerstiens учитывает, что request.is_secure() всегда возвращает False, если позади Heroku обратного прокси, а не "исправлено". Если я правильно помню, это вызовет цикл перенаправления HTTP.

Если вы используете Django с gunicorn, другой способ сделать это - добавить следующее в конфигурацию gunicorn

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

Запустите с таким же образом в вашем Procfile

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

Установив gunicorn secure-scheme-header, request.is_secure() будет правильно возвращать True по запросам https. См. Конфигурация Gunicorn.

Теперь промежуточное программное обеспечение @CraigKerstiens будет работать правильно, включая любые вызовы request.is_secure() в вашем приложении.

Примечание. Django также имеет тот же самый параметр настройки конфигурации SECURE_PROXY_SSL_HEADER, но в версии dev.

Ответ 4

Какие рамки вы используете для своего приложения? Если вы используете Django, вы можете просто использовать некоторое промежуточное ПО, похожее на:

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)

Ответ 5

Если вы используете Flask, это работает достаточно хорошо:

1) Сделайте "pip install flask-sslify"

(github здесь: https://github.com/kennethreitz/flask-sslify)

2) Включите следующие строки:

from flask_sslify import SSLify
if 'DYNO' in os.environ: # only trigger SSLify if the app is running on Heroku
    sslify = SSLify(app)