2013-02-27 19 views
7

Wenn ich versuche, eingehenden Datenverkehr auf HTTPS umzuleiten, erhalte ich eine unendliche Weiterleitungsschleife.HTTP auf HTTPS auf Flask + Heroku umleiten

@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']) 

Die request.url wird nie in Präfix https geändert. Ich möchte Herokus Huckepack-SSL verwenden, um die Kosten zu minimieren.

Antwort

6

Auf Heroku wird SSL (https) beendet, bevor es Ihre Anwendung erreicht, so dass Ihre App SSL-Datenverkehr nie wirklich sieht. Um zu prüfen, ob eine Anfrage mit https gestellt wurde, müssen Sie stattdessen den Header x-forwarded-proto prüfen. Weitere Informationen hier: How to make python on Heroku https only?

UPDATE: Für Ihre Verwendung sollten Sie request.url nach "myapp.herokuapp.com/checkout/" überprüfen; und vergewissern Sie sich, dass die Kopfzeile "https" ist

+0

Dank friism. Ich habe das Flaschen-Slify-Paket gesehen. Was meinen Bedürfnissen entspricht, außer dass ich eine benutzerdefinierte Domain zusammen mit der Subdomain von heroku verwende. Ich möchte nur SSL auf einer Seite setzen. Danke für das Dokument, ich werde es durchlesen. –

+0

Sie sollten einfach 'request.url' für" http://myapp.herokuapp.com/checkout/ "überprüfen und überprüfen, dass die Kopfzeile" https "ist. – friism

+1

Danke, das ist, was es getan hat. –

0

Ich war in der Lage, den Kolben-sslify-Code für eine einzige Ansicht zu verwenden. Nur benötigt, um zu überprüfen, ob die Anfrage mit SSL gemacht wurde oder nicht, und der Antwort korrekte Header hinzuzufügen. 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)

(Github ist hier Sie "Kolben-sslify pip install": https://github.com/kennethreitz/flask-sslify)

2) Fügen Sie die folgenden Zeilen:

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

Das ''DYNO' 'in os.environ' Tipp ist besonders nützlich. – awm

+0

Beachten Sie, dass es nur funktioniert, wenn 'app.debug = False' – tdc

4

Ich versuchte SSLify , url_for _scheme, und Festlegen eines PREFERRED_URL_SCHEME; aber keiner hat geklappt, zumindest bei Release-Level .. (funktionierte gut lokal) Dann dachte ich;

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

Dies ist im Wesentlichen eine andere Möglichkeit, es ohne Konfigurationen oder Erweiterungen zu erledigen.

+1

Dies führte zu" Diese Webseite hat eine Umleitungsschleife "für mich – tdc

+0

@tdc Interessant, haben Sie die Antwort versucht, die ich gab, bevor jemand diese Antwort bearbeitet? Ich habe das nicht versucht, obwohl es scheint, dass es genauso funktionieren sollte; Ich weiß, dass das Original definitiv gut funktioniert hat. – Miles

+0

Ich habe das Original nie gesehen! SSLify hat am Ende für mich funktioniert – tdc

0

Sie müssen nur die X-Forwarded-Proto Header überprüfen. Wenn es falsch ist, umleiten Sie auf die entsprechende https-URL.

Hier ist der Code https für alle Anrufe auf einen Kolben App läuft auf Heroku zu erzwingen:

@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) 
Verwandte Themen