1

I have a site running on google app engine with a private dns.

But every time I open that website it opens as http, I tried using a before_request decorator on flask to change http to https but I get too_many_redirects error, I also tried using ProxyFix but since my page don't have X-Forwarded-Proto as a header it doesn't redirect to the correct page.

EDIT: I forgot to mention that I'm using a flex environment

What is the best way to configure this behavior? Where can I set this configuration and if possible how can I set it?

This is how I was trying to redirect:

@app.before_request
def before_request():
    if request.endpoint in app.view_functions and request.headers.get('X-Forwarded-Proto', None) == 'http':
        code = 301
        return redirect(request.url.replace('http://', 'https://'), code=code)

Thx very much for the help!

Pedro Daumas
  • 171
  • 4
  • 14

4 Answers4

1

You can check https more directly using:

if request.environ.get('HTTPS') == 'off':
    return redirect(...)

or even:

if not request.is_secure:
    return redirect(...)

But you also have to deal with times you don't want a redirect (localhost, versions, cron jobs, etc.). Start with:

#so can test versions, don't redirect appspot urls:
if "appspot" in request.environ.get('HTTP_HOST'):
    return None

if os.environ['SERVER_NAME'].startswith('1') or os.environ['SERVER_NAME'].startswith('localhost'):
    return None

user_agent = request.environ.get('HTTP_USER_AGENT', 'fake')

# cron, taskqueue, module, development, no redirect
if (    'AppEngine-Google' in user_agent or 
        'my-module' in request.environ.get('CURRENT_MODULE_ID')):
    return None
GAEfan
  • 11,244
  • 2
  • 17
  • 33
0

check this out python flask redirect to https from http

@app.before_request
def before_request():
    if request.url.startswith('http://'):
        url = request.url.replace('http://', 'https://', 1)
        code = 301
        return redirect(url, code=code)
konst
  • 1
  • 2
0

Since you're using App Engine, you probably just want to change your app.yaml to always require the URL be secure. For example:

- url: .*
  script: main.app
  secure: always

The seucre: always flag ensures that all requests being routed with that rule are encrypted. No need to involve Flask at all.

Ken Kinder
  • 12,654
  • 6
  • 50
  • 70
  • I forgot to mention that I'm using a flex env, so the secure flag doesn't work – Pedro Daumas Oct 19 '18 at 18:25
  • I see. Well, if your proxy isn't adding `X-Forwarded-Proto`, I'm not sure what you can do to figure out how to add https. I'd say it's more an issue with your proxy than with Python or Flask, because they aren't involved then. I would, however, try making a page that prints out all your request headers to see if there's something being added you can use instead of `X-Forwarded-Proto`. – Ken Kinder Oct 19 '18 at 18:39
  • I already checked ou the request headers and there's no headers witth http ou https. Is there a way for me to see google`s app engine proxy or edit to send the X-Forwarded-Proto header? – Pedro Daumas Oct 19 '18 at 19:45
0

I am also running a flask app on app engine. Use flask-talisman and set force_https_permanent to true and force_https to true https://github.com/GoogleCloudPlatform/flask-talisman

talisman = Talisman( app, content_security_policy=csp, content_security_policy_nonce_in=['script-src'], force_https_permanent='true', force_https='true' )

The example above woold also add a csp which is also very useful for security .

theintense
  • 121
  • 1
  • 7