1
votes

I have a flask web app deployed to google app engine. However, it is not forcing my link to https. However, if I refresh it, it will go to the ssl https version. But the user can still remove the s and jump back into the http version. Is there any way to completely remove the http protocol on my site and have it redirect to the ssl version. Here is the app.yaml file I'm using currently. I also tried adding in redirect_http_response_code: 301 with no luck to remove the http protocol

runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
  python_version: 3.7

# This sample incurs costs to run on the App Engine flexible environment.
# The settings below are to reduce costs during testing and are not appropriate
# for production use. For more information, see:
# https://cloud.google.com/appengine/docs/flexible/python/configuring-your-app-with-app-yaml
manual_scaling:
  instances: 1
resources:
  cpu: 1
  memory_gb: 0.5
  disk_size_gb: 10

handlers:
- url: /.*
  secure: always
  script: auto
2

2 Answers

1
votes

I prefer not to install additional software packages for relatively simple things, so I do it myself. For GAE flex there are a few things to handle. I've added comments below to help explain.

@app.before_request
def redirect_http():
    # http -> https 
    if (
        # Flask tells us when request is http. This might not be needed for you but
        # I need it because I use this code for GAE standard as well.
        not request.is_secure and 
        # Load balancers forward https requests as http but set headers to let you 
        # know that original request was https
        not request.headers.get('X-Forwarded-Proto') == 'https' and 
        # GAE cron urls must be http
        not request.path.startswith("/cron")
        ): 
        return redirect("https" + request.url[4:], code=301)
    # naked domain -> www
    if request.url.startswith("https://example.com"):
        return redirect('https://www.' + request.url[8:], code=301)

The Flask packages recommended by @tzovourn do other important things as well so you may want to consider those (I personally do all those things myself since it isn't hard to do them).

0
votes

I noticed that you are using App Engine Flexible. As per documentation, setting secure: always in app.yaml doesn't work for App Engine Flexible.

Documentation recommends to secure your HTTP requests by using the Flask Talisman library.

Another way to configure your Flask application to redirect all incoming requests to HTTPS is to use the Flask-SSLify extension