Redirect HTTP to HTTPS on Flask+Heroku
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.
Related videos on Youtube
Comments
-
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 about 9 yearsThe
'DYNO' in os.environ
tip is particularly useful. -
tdc over 8 yearsThis resulted in "This webpage has a redirect loop" for me
-
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 over 8 yearsI never saw the original! SSLify worked for me in the end