Google OAuth2部署至Heroku登录弹窗报400 Bad Request问题
故障根因
从你提供的失败请求特征和环境差异,核心触发原因按概率从高到低排序:
- 前端传参非法(概率90%+):你贴的400请求URL里明确携带了非法参数
width=undefined。Google Identity Services(GSI)的按钮渲染接口对参数合法性校验非常严格,width字段仅接受正整数像素值或官方约定的枚举值,传入JS的undefined值会被接口直接拒绝返回400,导致登录按钮iframe加载失败、弹窗白屏。本地环境正常是因为开发模式下对应配置变量走了本地硬编码默认值,生产构建时该变量未被正确注入(比如漏配环境变量、变量作用域问题),最终拿到undefined传给了GSI初始化方法。 - 授权源不匹配(剩余概率):如果修复传参后仍报错,大概率是生产环境实际请求的Origin和你在Google Cloud Console配置的Authorized origins不完全一致,GSI对跨域授权源做严格全匹配校验,协议、域名、端口任意一项不匹配都会返回403/400。
排查解决步骤
- 优先修复width传参问题:
定位前端初始化GSI登录按钮的代码段,检查传入配置对象的width字段赋值逻辑,绝对不要把可能为undefined的变量直接透传给GSI。
典型错误写法示例:
修复方案二选一即可:要么直接删除width配置项,让GSI自动适配按钮容器宽度;要么给参数加合法兜底值,比如google.accounts.id.renderButton( document.getElementById('google-login-btn'), { type: 'standard', theme: 'outline', size: 'large', width: window.GOOGLE_BTN_WIDTH // 生产环境该变量未定义,值为undefined } )width: window.GOOGLE_BTN_WIDTH || 320。修复后重新构建部署,先确认请求URL里不再出现width=undefined,再验证按钮加载状态。 - 校验授权源配置一致性:
打开生产站点页面,在浏览器控制台执行window.location.origin拿到当前页面的真实源地址,和Google Cloud Console中OAuth客户端的Authorized origins列表逐字符对比,必须完全匹配:- 确认协议一致:生产环境是https就不能配置成http
- 确认域名一致:检查有没有自动跳转到带www的子域名、有没有拼写错误
- 确认端口一致:如果生产服务用了非443/80的自定义端口,必须把端口号加到配置里
新增缺失的授权源后,等待2-5分钟让Google侧配置生效再测试。
- 校验重定向URI配置:
检查前端代码里初始化GSI时传入的redirect_uri参数,必须和控制台Authorized redirect URIs列表中的某一项完全一致,不能多末尾斜杠、不能多路径后缀,比如配置值是https://my-app.herokuapp.com,代码里就不能写成https://my-app.herokuapp.com/。 - 排除缓存干扰:
所有配置和代码修改完成后,用浏览器无痕模式打开生产站点测试,避免本地缓存的旧Cookie、旧静态资源导致的假报错。
内容的提问来源于stack exchange,提问作者mdmb
相关产品推荐
相关产品推荐

