2013-02-27 4 views
7

Когда я пытаюсь перенаправить входящий трафик на https, я получаю бесконечный цикл перенаправления.Перенаправление HTTP на HTTPS на Flask + Heroku

@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. Я хочу использовать контрейлерные ssl герою, чтобы минимизировать затраты.

ответ

6

В Heroku SSL (https) прекращается до того, как он достигнет вашего приложения, поэтому приложение никогда не видит SSL-трафик. Чтобы проверить, был ли запрос сделан с помощью https, вам необходимо проверить заголовок x-forwarded-proto. Больше информации здесь: How to make python on Heroku https only?

ОБНОВЛЕНИЕ: Для вашего использования вы должны просто проверить request.url для «myapp.herokuapp.com/checkout/»; и убедитесь, что заголовок «https»

+0

Спасибо friism. Я видел пакет с флагом-sslify. Который отвечал бы моим потребностям, за исключением того, что я использую собственный домен вместе с поддоменом герою. Я только хочу поставить SSL на одну страницу. Спасибо за док, хотя я прочитаю его. –

+0

Вы должны просто проверить 'request.url' для« http://myapp.herokuapp.com/checkout/ »и убедиться, что заголовок« https » – friism

+1

Спасибо, вот что он сделал. –

0

Мне удалось перевернуть код флагов-sslify для одного вида. Просто нужно проверить, выполнялся ли запрос с помощью 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 здесь: 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

«DYNO» в подсказке os.environ особенно полезен. – awm

+0

Обратите внимание, что это работает только в том случае, если 'app.debug = False' – tdc

4

Я пытался SSLify , 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. Если его ложь, переадресуйте на эквивалентный URL-адрес https.

Вот код для обеспечения HTTPS для всех вызовов на приложение опоки, выполняющихся на Heroku:

@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) 
Смежные вопросы