Kri*_*ian 65
将@CraigKerstiens和@allanlei的答案结合到我测试过的内容中,并验证可行.当请求是ssl时,Heroku将HTTP_X_FORWARDED_PROTO设置为https,我们可以使用它来检查:
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)
Run Code Online (Sandbox Code Playgroud)
sha*_*iao 50
Django 1.8将支持非HTTPS重定向(从django-secure集成):
SECURE_SSL_REDIRECT = True # [1]
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
Run Code Online (Sandbox Code Playgroud)
为了SECURE_SSL_REDIRECT处理你必须使用SecurityMiddleware:
MIDDLEWARE = [
...
'django.middleware.security.SecurityMiddleware',
]
Run Code Online (Sandbox Code Playgroud)
[1] https://docs.djangoproject.com/en/1.8/ref/settings/#secure-ssl-redirect
All*_*Lei 13
不确定@ CraigKerstiens的答案是否考虑到如果在Heroku的反向代理之后request.is_secure()总是返回False而不是"修复".如果我没记错的话,这将导致HTTP重定向循环.
如果您使用gunicorn运行Django,另一种方法是将以下内容添加到gunicorn的配置中
secure_scheme_headers = {
'X-FORWARDED-PROTO': 'https'
}
Run Code Online (Sandbox Code Playgroud)
在Procfile中运行类似的东西
web: python manage.py run_gunicorn -b 0.0.0.0:$PORT -c config/gunicorn.conf
Run Code Online (Sandbox Code Playgroud)
通过设置gunicorn secure-scheme-header,request.is_secure()将正确返回Truehttps请求.见Gunicorn Config.
现在@ CraigKerstiens的中间件可以正常工作,包括request.is_secure()你的应用程序中的任何调用.
注意:Django也有相同的配置设置调用SECURE_PROXY_SSL_HEADER,但在开发版本中.
您使用什么框架来申请?如果你正在使用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)
Run Code Online (Sandbox Code Playgroud)
2020年更新:
如果您使用 Flask,我会推荐以下内容:
@app.before_request
def before_request():
if 'DYNO' in os.environ:
if request.url.startswith('http://'):
url = request.url.replace('http://', 'https://', 1)
code = 301
return redirect(url, code=code)
Run Code Online (Sandbox Code Playgroud)
以上在 Heroku 上效果很好,并允许您http在本地开发中使用heroku local.
Flask-SSLify 不再维护,也不再受到 Flask 社区的正式支持。
2014 原始答案:
如果您使用的是 Flask,这很有效:
(github 在这里:https : //github.com/kennethreitz/flask-sslify)
from flask_sslify import SSLify
if 'DYNO' in os.environ: # only trigger SSLify if the app is running
on Heroku
sslify = SSLify(app)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17488 次 |
| 最近记录: |