2013-02-27 20 views
7

पर HTTP को HTTPS पर रीडायरेक्ट करें जब मैं आने वाले ट्रैफ़िक को 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 में नहीं बदला जाता है। मैं लागत कम करने के लिए heroku के piggyback एसएसएल का उपयोग करना चाहता हूँ।

उत्तर

6

हेरोकू पर, एसएसएल (https) को आपके एप्लिकेशन तक पहुंचने से पहले समाप्त कर दिया गया है, इसलिए आप वास्तव में एसएसएल यातायात को कभी नहीं देखते हैं। यह जांचने के लिए कि क्या https के साथ अनुरोध किया गया था, आपको इसके बजाय x-forwarded-proto शीर्षलेख का निरीक्षण करना होगा। यहां अधिक जानकारी: How to make python on Heroku https only?

अद्यतन: आपके उपयोग के लिए, आपको केवल "myapp.herokuapp.com/checkout/" के लिए request.url की जांच करनी चाहिए; और सत्यापित करें कि हेडर "https"

+0

धन्यवाद friism। मैंने फ्लास्क-एसस्लिफ़ पैकेज देखा है। जो मेरी जरूरतों को पूरा करेगा, सिवाय इसके कि मैं उसके डोमेन के सबडोमेन के साथ एक कस्टम डोमेन का उपयोग कर रहा हूं। मैं केवल एक पेज पर एसएसएल रखना चाहता हूं। डॉक्टर के लिए धन्यवाद हालांकि, मैं इसके माध्यम से पढ़ूंगा। –

+0

आपको "http://myapp.herokuapp.com/checkout/" के लिए केवल request.url' की जांच करनी चाहिए और सत्यापित करना है कि हेडर "https" – friism

+1

धन्यवाद, यही है। –

0

मैं एकल दृश्य के लिए फ्लास्क-एसस्लिफ़ कोड को दोबारा करने में सक्षम था। एसएसएल के साथ अनुरोध किया जा रहा था या नहीं, यह जांचने के लिए बस जरूरी है कि प्रतिक्रिया में उचित शीर्षलेख जोड़ें। 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 यहाँ है "कुप्पी के sslify स्थापित पिप" है: 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

os.environ' टिप में 'DYNO' विशेष रूप से उपयोगी है। – 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 शीर्षलेख की जांच करने की आवश्यकता है। यदि यह गलत है, तो बराबर 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)