Redirect HTTP to HTTPS on Flask+Heroku

10,279

Solution 1

On Heroku, SSL (https) is terminated before it reaches your application, so you app never actually sees SSL traffic. To check whether a request was made with https, you instead have to inspect the x-forwarded-proto header. More info here: How to make python on Heroku https only?

UPDATE: For your use, you should just check request.url for "myapp.herokuapp.com/checkout/"; and verify that the header is "https"

Solution 2

1) Do "pip install flask-sslify"

(github is here: https://github.com/kennethreitz/flask-sslify)

2) Include the following lines:

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

Solution 3

I tried SSLify, url_for _scheme, and setting a PREFERRED_URL_SCHEME; however none worked out, at the release level at least.. (worked fine locally) Then I thought;

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

This is essentially another way to get it done without any configurations, or extensions.

Share:
10,279

Related videos on Youtube

The Internet
Author by

The Internet

yea

Updated on September 11, 2022

Comments

  • The Internet
    The Internet over 1 year

    When I attempt to redirect incoming traffic to https I get an infinite redirect loop.

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

    The request.url is never changed to prefix https. I want to use heroku's piggyback ssl to minimize cost.

  • awm
    awm about 9 years
    The 'DYNO' in os.environ tip is particularly useful.
  • tdc
    tdc over 8 years
    This resulted in "This webpage has a redirect loop" for me
  • Miles
    Miles over 8 years
    @tdc Interesting, did you try the answer I gave before someone edited this answer? I haven't tried this, although it seems it should work the same; I know the original definitely worked fine.
  • tdc
    tdc over 8 years
    I never saw the original! SSLify worked for me in the end