部署在Google Cloud Run的Flask应用OpenID认证重定向URI不匹配解决方法
Flask部署在Google Cloud Run上的Google OpenID重定向URI不匹配问题解决
思路纠正
不需要让Flask监听HTTPS请求,核心问题是Flask不知道自己运行在HTTPS反向代理(Cloud Run)之后,因此生成的回调URL默认使用了HTTP协议。正确的思路是配置Flask识别反向代理传递的HTTPS环境信息,生成符合要求的HTTPS回调地址。
具体实现方法
1. 启用ProxyFix中间件(关键步骤)
Cloud Run会通过X-Forwarded-Proto等HTTP头部告知Flask原始请求的协议是HTTPS,我们需要让Flask信任这些头部并据此生成正确的URL。使用Werkzeug的ProxyFix中间件即可实现:
from flask import Flask from werkzeug.middleware.proxy_fix import ProxyFix app = Flask(__name__) # 配置ProxyFix,信任反向代理传递的协议、主机等头部 app.wsgi_app = ProxyFix( app.wsgi_app, x_for=1, # 信任X-Forwarded-For头部 x_proto=1, # 信任X-Forwarded-Proto头部(获取原始请求协议) x_host=1, # 信任X-Forwarded-Host头部(获取原始请求主机) x_prefix=1 # 信任X-Forwarded-Prefix头部 )
2. 用Flask内置方法生成回调URL
避免手动拼接URL,改用url_for生成带完整协议的外部URL,确保协议自动匹配反向代理传递的信息:
from flask import url_for @app.route("/login") def login(): client = WebApplicationClient(google_client_id) google_provider_config = requests.get('https://accounts.google.com/.well-known/openid-configuration').json() authorization_endpoint = google_provider_config["authorization_endpoint"] # 使用url_for生成回调地址,_external=True会生成完整的绝对URL redirect_uri = url_for('callback', _external=True) request_uri = client.prepare_request_uri( authorization_endpoint, redirect_uri=redirect_uri, scope=["openid", "email", "profile"] ) return redirect(request_uri)
3. 可选:全局设置默认协议(适合纯生产环境)
如果你的应用只在Cloud Run等HTTPS环境运行,可以全局设置Flask的默认URL协议:
app.config['PREFERRED_URL_SCHEME'] = 'https'
但这种方法不如ProxyFix灵活,无法兼顾本地HTTP开发环境,因此优先推荐ProxyFix方案。
原理说明
Google Cloud Run作为反向代理,会接收外部HTTPS请求,转换为HTTP请求转发给你的Flask应用,同时通过X-Forwarded-Proto: https头部告知Flask原始请求的协议。ProxyFix中间件会让Flask使用这些头部信息替代默认的HTTP协议,从而生成正确的HTTPS回调URL,解决重定向URI不匹配的问题。
内容的提问来源于stack exchange,提问作者emanuele_f
相关产品推荐
相关产品推荐

