You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署在Render.com的Flask应用Google OAuth登录遭遇redirect_uri_mismatch(400)错误求助

部署在Render.com的Flask应用Google OAuth登录遭遇redirect_uri_mismatch(400)错误求助

兄弟我之前在Render上部署Flask+Google OAuth的时候,完完全全踩过一模一样的坑!你的问题核心其实是Render作为反向代理平台,Flask默认没识别到外部的HTTPS请求——虽然你浏览器里看的是https,但Flask本身跑在Render的反向代理后面,收到的是来自代理的http请求,所以生成redirect_uri的时候就用了http,这就导致和你在Google控制台配置的https URI不匹配,直接触发400错误。

给你一步步捋解决方法,都是我亲测有效的:

  • 第一步:给Flask加上反向代理识别的中间件(最关键!)
    Render会给你的应用传递X-Forwarded-Proto和X-Forwarded-Host这两个头,告诉Flask外部用户用的是https协议,但Flask默认不信任这些头。你需要用Werkzeug的ProxyFix中间件来让Flask识别这些头:
    在你的Flask代码里加上这段(要放在app创建完成之后、注册蓝图之前):
from werkzeug.middleware.proxy_fix import ProxyFix

# 告诉Flask信任反向代理的协议和主机头,这样它就知道外部是HTTPS了
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)

这一步是核心,加了之后Flask生成的所有URL(包括OAuth的redirect_uri)都会自动用https,再也不会出现http的情况了。

  • 第二步:简化Flask-Dance的Blueprint配置,别硬编码redirect_url
    你代码里硬写了redirect_url其实没必要,反而容易因为域名变动或者协议问题出bug。Flask-Dance会自动根据Flask的当前协议生成正确的redirect_uri,只要第一步做好了,直接删掉redirect_url参数就行:
google_bp = make_google_blueprint(
    client_id=os.environ["GOOGLE_CLIENT_ID"],
    client_secret=os.environ["GOOGLE_CLIENT_SECRET"],
    scope=["profile", "email"],
    # 删掉这里的redirect_url,让它自动生成正确的回调地址
)
app.register_blueprint(google_bp, url_prefix="/login")

如果一定要指定回调逻辑,也别硬编码完整URL,用redirect_to参数指向你的回调视图函数名(比如你有个处理授权的视图叫google_authorized,就写redirect_to="google_authorized"),这样更灵活也不容易错。

  • 第三步:清理Google Cloud Console的Redirect URIs配置
    之前你加了http和https的URI,现在可以把http的删掉了——Google OAuth在生产环境(非本地调试)是强制要求HTTPS的,留着http的URI不仅没用,还会触发安全提示。只保留https://storytrack.org/login/google/authorized这一条就行。

补充下你之前的尝试:你说加了http URI后能跳但提示需要HTTPS,就是因为Google不允许生产环境用http的redirect_uri,这只是个临时的绕路方法,根本解决还是得让Flask生成正确的https地址。

另外给你个小tip:Render会自动给你设置RENDER_EXTERNAL_URL环境变量,值就是你的应用的https完整地址,之后如果代码里需要引用域名,直接用这个变量就好,不用硬编码,省得后续改域名又出问题。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 06:40:31