2011-12-08 8 views
47

私はHeroku(Cedarスタック)上にpython/djangoアプリケーションを持っており、https上でのみアクセス可能にしたいと考えています。私は "sslピギーバック"オプションを有効にして、https経由で接続することができます。Heroku httpsのみでpythonを作る方法は?

しかし、httpアクセスを無効にする、またはhttpsにリダイレクトする最良の方法は何ですか?

答えて

63

@CraigKerstiensと@allanleiの回答を何かに組み合わせることで、私はテストして、動作することを確認しました。リクエストがSSLであるとき、Herokuのは、httpsにHTTP_X_FORWARDED_PROTOを設定し、我々はこれを確認するために使用することができます。

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

回答は今すぐ[github上のアプリケーション](https://github.com/rdegges/django-sslify) –

+1

githubを置くためのUpvote ...ありがとう!ちょうど私が今日探していたもの。 –

+3

DEBUGがTrueに設定されている場合は、これは機能しません。それを考えると1時間かかりましたので、これで誰かが時間を節約できます。 – Femi

6

アプリケーションにはどのようなフレームワークを使用していますか?あなたはジャンゴを使用している場合は、簡単な使用にはいくつかのミドルウェア同様の可能性:request.is_secure()は常にHerokuののリバースプロキシではなく後ろに「固定」場合False返すこと

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

はい、私はdjangoを使用しています。答えてくれてありがとうございます:もっと簡単なもの(隠されたヒロクのオプションのようなもの)が表示されない限り、試してみてください。 – Kristian

+0

私はあなたに少し微調整を加えなければなりませんでしたが、モデレータは私の編集を拒否しました。私はあなたの現在の答えで終わりのないリダイレクトの問題を解決する私自身の答えを作成しました。とにかくおかげさまで、あなたの貢献なしにミ​​ドルウェアソリューションを考えたことはありませんでした。 – Kristian

+1

このソリューションは、終わりのないリダイレクトループを作成します。上記の私の答えを参照してください。 – Kristian

13

わからないの@ CraigKerstiensかの答えが考慮されます。正しく覚えていれば、HTTPリダイレクトループが発生します。

あなたはgunicornとジャンゴを実行している場合は、それを行うための別の方法は、gunicorn年代を設定することでのあなたのProcfile

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

でこのようないくつかで設定

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

実行をgunicornに以下を追加することですsecure-scheme-headerrequest.is_secure()はhttpsリクエストで正しくTrueを返します。 Gunicorn Configを参照してください。

あなたのアプリにrequest.is_secure()への呼び出しを含め、@ CraigKerstiensのミドルウェアが正しく動作するようになりました。

注:Djangoは同じ設定設定コールSECURE_PROXY_SSL_HEADERを持っていますが、それは開発版です。

+2

django SECURE_PROXY_SSL_HEADER設定はメインラインで利用できるようになりました(確かに1.6、おそらくそれ以前)。 – Symmetric

4

あなたはフラスコを使用している場合、これは非常にうまく機能:

1)「flask-をインストールPIPください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) 
+0

もし私たちがこれを行うなら、我々はまだHerokuものをする必要がありますか?ごめんなさい。 – John

+0

https://github.com/kennethreitz/flask-sslify/issues/3の "flip-flopping"の問題を参照してください。 – wodow

33

ジャンゴ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

+0

これは、pipパッケージsslifyがDjango 1.8以降で廃止されたことを意味しますか? – dfrankow

+0

@dfrankow django-sslifyはdjango-secureと似ていますが、パッケージ作成者 – shangxiao

+0

@ dfrankowと確認する必要はありません。httpからhttpsに自動的にリダイレクトするには、Django 1.8でsslifyが必要です。 –

関連する問題