Как сделать 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)