Flask+oauth2client部署后OAuth重定向至HTTP而非HTTPS问题排查
刚好我之前在App Engine上部署Flask+oauth2client应用时也碰到过一模一样的问题,咱们来聊聊问题出在哪,以及怎么解决:
问题根源
这本质是反向代理的协议传递问题:
- App Engine的前端负载均衡会帮你处理HTTPS请求,然后把请求以HTTP的形式转发给你的Flask后端应用。这就导致Flask内部拿到的请求协议是HTTP,当
url_for生成重定向URL时,会默认用这个HTTP协议,最终重定向回到HTTP地址。 - 另外,
oauth2client在处理谷歌认证的回调时,也是基于当前请求的scheme来构建跳转地址的,同样会因为后端拿到的是HTTP请求,生成HTTP的回调URL,认证完成后自然就跳回HTTP了。
解决办法
我整理了几个有效的方案,你可以根据自己的情况选择:
1. 让Flask识别真实的请求协议(最推荐)
Flask可以通过ProxyFix中间件来信任App Engine传递的X-Forwarded-Proto头(这个头里存的是用户真实请求的协议,也就是HTTPS)。在你的Flask初始化代码里加上这段:
from flask import Flask from werkzeug.middleware.proxy_fix import ProxyFix app = Flask(__name__) # 配置ProxyFix,信任X-Forwarded-Proto头 app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1)
这样Flask就能正确获取到真实的请求协议,url_for生成的重定向URL就会是HTTPS的了。
2. 强制Flask全局使用HTTPS生成URL
如果不想配置中间件,也可以直接设置Flask的全局配置,强制所有url_for生成的URL都用HTTPS:
app = Flask(__name__) app.config['PREFERRED_URL_SCHEME'] = 'https'
这个方法简单直接,但灵活性稍差——不管后端拿到的请求协议是什么,都会生成HTTPS的URL。
3. 在App Engine层面强制HTTPS跳转
针对App Engine环境,你可以直接在app.yaml里配置路由,强制所有请求跳转到HTTPS:
标准环境:
handlers: - url: /.* script: auto secure: always
弹性环境:
runtime: python env: flex service: your-service-name handlers: - url: /.* secure: always redirect_http_response_code: 301
这个配置会让App Engine的负载均衡直接把所有HTTP请求重定向到HTTPS,从根源上避免HTTP请求进入后端。
4. 明确指定oauth2client的HTTPS回调地址
检查你的oauth2client配置,手动指定HTTPS的回调地址,而不是让它自动生成:
from oauth2client.client import OAuth2WebServerFlow flow = OAuth2WebServerFlow( client_id='你的客户端ID', client_secret='你的客户端密钥', scope='需要的权限范围', redirect_uri='https://xxx.appspot.com/home' # 明确写HTTPS的回调地址 )
这样谷歌认证完成后,会直接跳转到你指定的HTTPS地址,不会出现协议切换的问题。
内容的提问来源于stack exchange,提问作者Arhire Ionut
相关产品推荐
相关产品推荐

