passport.js对接GraphQL API实现谷歌认证偶发InternalOAuthError求助
问题原因
你遇到的InternalOAuthError: Failed to fetch user profile错误来源于两个层面:
- 底层层面:passport-google-oauth20向Google的用户信息接口发起请求时,出现了网络波动、接口限流、请求超时等偶发问题,这类属于第三方接口调用的常见偶发异常。
- 代码层面:你的passport验证回调函数存在异步逻辑处理错误,不仅会导致部分逻辑分支异常,也会放大偶发接口错误的影响。
修复方案
1. 修复验证回调的异步逻辑错误
你当前的代码中,User.find、User.create都是异步Promise操作,外层的try/catch无法捕获Promise抛出的异常,且你没有等待数据库操作完成就提前调用了done方法,同时存在用户已存在时未调用done的逻辑漏洞。
替换你的passport配置中的验证回调为如下async/await写法,覆盖所有逻辑分支并捕获异步错误:
passport.use( new GoogleStrategy( { clientID: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, callbackURL: 'http://localhost:4001/auth/google/callback', passReqToCallback: true, }, // 改为async异步函数 async (req, _accessToken, _refreshToken, profile, done) => { try { // 等待数据库查询完成 const res = await User.find({ where: { id: profile.id }, }) console.log(res) if (res.length === 0) { const newUser = { id: profile.id, firstName: profile.name?.givenName, lastName: profile.name?.familyName, email: profile.emails?.[0]?.value, } // 等待新用户创建完成 await User.create({ input: [newUser], }) } req.user = profile // 所有正常分支统一调用done done(null, profile) } catch (error: any) { // 捕获所有同步+异步错误 done(error) } } ) )
同时删除/auth/google/callback路由的passport认证配置中多余的scope参数,scope仅需要在首次跳转授权的/auth/google路由中配置即可,回调中不需要重复配置。
2. 优化Google策略的请求配置,降低偶发错误概率
可以给Google OAuth请求添加超时时间,减少长时间等待导致的错误,配置方式如下:
const googleStrategy = new GoogleStrategy(/* 原有配置 */) // 设置请求超时时间为10秒 googleStrategy._oauth2.setTimeout(10000) passport.use(googleStrategy)
如果错误出现频率较高,可以在策略的userProfile方法中添加重试逻辑,针对偶发的网络失败自动重试2-3次。
内容的提问来源于stack exchange,提问作者Lawand
相关产品推荐
相关产品推荐

