2013-02-27 20 views
7

着信トラフィックをhttpsにリダイレクトしようとすると、無限のリダイレクトループが発生します。Flask + HerokuのHTTPからHTTPSへのリダイレクト

@app.route('/checkout/')                                               
def checkout():                                                 
    checkout = "https://myapp.herokuapp.com/checkout/"                                    
    if checkout != request.url:                                            
     print checkout, request.url                                            
     return redirect(checkout)                                            
    return render_template('checkout.html', key=keys['publishable_key']) 

request.urlは、接頭辞httpsに決して変更されません。私はherokuのピギーバックSSLを使用してコストを最小限に抑えたいと思っています。

答えて

6

ヘロクでは、SSL(https)はアプリケーションに到達する前に終了しているため、実際にSSLトラフィックが検出されることはありません。リクエストがhttpsで行われたかどうかを確認するには、代わりにx-forwarded-protoヘッダーを調べる必要があります。詳細はこちら:How to make python on Heroku https only?

更新:ご使用の場合は、 "myapp.herokuapp.com/checkout/"のrequest.urlを確認してください。ヘッダーが「https」であることを確認してください

+0

ありがとうfriism。私はフラスコパッケージを見ました。私はherokuのサブドメインと一緒にカスタムドメインを使用していますが、私のニーズに合っています。私は1ページにSSLを入れたいだけです。しかし、docのおかげで、私はそれを読むでしょう。 –

+0

「http://myapp.herokuapp.com/checkout/」に対して 'request.url'をチェックし、ヘッダーが「https」であることを確認するだけです – friism

+1

ありがとうございました。 –

0

フラスコのコードを単一のビューに再利用することができました。要求がSSLで行われているかどうかを確認し、応答に適切なヘッダーを追加するだけでした。 https://github.com/kennethreitz/flask-sslify

@app.route('/checkout/')                                               
def checkout():                                                 
    checkout = "https://myapp.herokuapp.com/checkout/"                                    
    if request.headers.get('X-Forwarded-Proto', 'http') == 'https':                                    
     resp = make_response(render_template('checkout.html', key=keys['publishable_key']))                            
     return set_hsts_header(resp)                                            
    return redirect(checkout, code=302)                                           

def set_hsts_header(response):                                             
    """Adds HSTS header to each response."""                                          
    response.headers.setdefault('Strict-Transport-Security', hsts_header)                                  
    return response                                                

def hsts_header():                                                
    """Returns the proper HSTS policy."""                                          
    hsts_policy = 'max-age={0}'.format(31536000) #year in seconds                                    
    if self.hsts_include_subdomains:                                            
     hsts_policy += '; includeSubDomains'                                          
     return hsts_policy 
10

1)

"をフラスコ-sslifyインストールピップ" でください(githubのはここにある:

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

os.environのtipの '' DYNO 'は特に便利です。 – awm

+0

'app.debug = False'の場合にのみ動作することに注意してください – tdc

4

私はSSLifyを試してみました:https://github.com/kennethreitz/flask-sslify

2)次の行を含めます、url_for _scheme、およびPREFERRED_URL_SCHEMEを設定します。しかし、少なくともリリースレベルではうまくいきませんでした。(ローカルでうまく働いていました)そして、私は考えました。

@app.before_request 
def beforeRequest(): 
    if not request.url.startswith('https'): 
     return redirect(request.url.replace('http', 'https', 1)) 

これは、基本的な設定や拡張を行わない別の方法です。

+1

これは私のために"このウェブページにリダイレクトループがあります " – tdc

+0

@tdc興味深いことに、誰かがこの回答を編集する前に回答を試みましたか?私はこれを試していませんが、同じように動作するはずです。私は原作が間違いなくうまく働いたことを知っ – Miles

+0

私はオリジナルを見たことがない! SSLifyは私のために終わりに働いた – tdc

0

X-Forwarded-Protoヘッダーを確認するだけです。 falseの場合は、同等のhttps URLにリダイレクトします。ここで

Herokuの上で実行されているフラスコアプリ上のすべてのコールにHTTPSを強制するコード:

@app.before_request 
def enforceHttpsInHeroku(): 
    if request.headers.get('X-Forwarded-Proto') == 'http': 
    url = request.url.replace('http://', 'https://', 1) 
    code = 301 
    return redirect(url, code=code) 
関連する問題