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

Heroku部署的Express应用中passport-google-oauth20登录后触发应用错误的问题排查

问题分析与解决方案

核心原因

Heroku 作为反向代理平台,所有外部请求都会先经过 Heroku 的负载均衡器再转发到你的 Express 应用。默认情况下,Express 会认为这些转发过来的请求是 HTTP 协议,而不是用户实际发起的 HTTPS 请求。这就导致 Passport 生成的 Google OAuth 回调 URL 使用了 http:// 协议,但你在 Google 开发者控制台配置的授权重定向 URI 是 https://,两者不匹配触发了 Google 的安全校验错误,最终显示 Heroku 的「Application error」页面。不过此时 OAuth 流程其实已经完成(用户信息已存入 MongoDB),所以直接访问主页会处于登录状态。


解决方案

1. 让 Express 信任 Heroku 的反向代理

在你的根目录 index.js 中,初始化 Express 应用后立即添加以下代码,让 Express 从 Heroku 提供的 X-Forwarded-Proto 请求头中获取真实的请求协议:

const app = express()

// 添加这一行,让Express信任Heroku的反向代理
app.set('trust proxy', true);

// 后续的中间件配置...

这一步是关键,它会让 req.protocol 正确返回用户实际使用的 https,从而让 Passport 生成符合 Google 配置的 HTTPS 回调 URL。

2. 确认 Google 开发者控制台的重定向 URI 完全匹配

检查你在 Google Cloud Console 中配置的「授权重定向 URI」是否和 Heroku 应用的回调路径完全一致,格式必须为:

https://<你的Heroku应用域名>/auth/google/callback

比如你的应用域名是 my-app.herokuapp.com,那么 URI 就是 https://my-app.herokuapp.com/auth/google/callback,必须包含完整的 https 协议和正确的路径。

3. (可选)修正 User 模型字段匹配问题

看你的代码里,Passport 查找用户用的是 User.findOne({ googleId: profile.id }),但创建新用户时的字段是 Id: profile.id,这里可能存在字段不匹配的问题(如果你的 User 模型里存储 Google ID 的字段是 googleId 的话)。建议把 newUser 里的字段改为:

const newUser = {
  googleId: profile.id, // 改为googleId,和查找条件一致
  provider: profile.provider,
  displayName: profile.displayName,
  firstName: profile.name.givenName,
  lastName: profile.name.familyName,
  image: profile.photos[0].value,
  email: profile.emails[0].value,
}

否则可能会导致每次登录都创建新用户,而不是匹配已存在的用户。


验证步骤

  1. 将修改后的代码重新部署到 Heroku
  2. 清除浏览器缓存或使用无痕模式测试登录流程
  3. 查看 Heroku 日志(你写的 log 中间件会打印 request.protocol),确认请求协议已经变为 https

这样就能解决回调时的协议不匹配问题,登录后会正常跳转到主页,而不会停留在错误页面。

内容的提问来源于stack exchange,提问作者Dee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:32:42