oauth2.0 在多个护照策略之间关联用户数据

vatpfxk5  于 2023-02-11  发布在  其他
关注(0)|答案(1)|浏览(118)

我使用node,express,express-session,mongoose和passport-discord来验证用户身份,但我也希望使用passport-steam来选择性地将用户的steam帐户链接到他们的discord帐户。
问题是,为了链接他们的steam帐户,我还需要一种方法来了解哪个discord用户正在尝试这样做,但身份验证回调不包括任何访问当前会话的请求/响应头,并且我存储discord用户的数据库中没有任何steam数据,直到steam的身份验证回调被调用。在这一点上,我不知道是哪个不和谐的用户试图验证他们的Steam帐户。
为了帮助解决这个问题,我设置了3个mongoose模型,使其具有3个独立的数据库集合:

  • DiscordUser(存储不一致用户信息,包括其discordId)
  • SteamUser(存储蒸汽用户信息,包括其steamId)
  • 用户(存储必需的discordId和可选的steamId)

然后,我尝试序列化和反序列化User对象,但passport.deserializeUser(obj, done)方法似乎传入了一个id,而不是User对象,并且我无法确定它是discordId还是steamId,也无法确定我要为哪个不一致用户反序列化SteamUser,因此我最终回到了起点。
关联这些用户的最佳方法是什么?
如果需要,我可以提供一些代码片段的要求。

6ie5vjzr

6ie5vjzr1#

i found an article,这有助于解决这个问题。
我是这么做的:

  • new Strategy(...)选项中使用passReqToCallback: true
  • 在两个策略回调函数中,添加req作为第一个参数

(ie.,async function callback(req, accessToken, refreshToken, profile, done) { ... }
然后改变这个:

router.get('/steam', passport.authenticate('steam'), (req, res) => {
  //...
});

对此:

// Note that the route here is the same as the callback/redirect
router.get('/steam/redirect', (req, res, next) => {
  passport.authenticate('steam', (err, user, { nextRoute }) => {
    if (err)
      return next(err);

    if (nextRoute) {
      // user was authorized with provider?
      // send em back to profile
      return res.redirect(nextRoute);
    } else {
      // give em some cookies
      req.logIn(user, err => {
        if (err)
          return next(err);

        return res.redirect('/');
      });
    }
  })(req, res, next)
});

最后,修改User模型模式以包含sessionID,可以通过req.sessionID(或req.session.sessionID 从两种策略的回调函数中访问sessionID
这样,我就可以在成功登录时使用我的主策略更新数据库(s)(在本例中为discord),然后从次要策略中引用它(在这种情况下为流),提供足够的时间来更新User数据库,以便只要会话仍然有效就具有每个策略之间的链接信息。您总是可以简单地在代码中的任何地方引用User数据库来检查有效的主要 * 和 * 次要策略ID,允许您交叉引用其他数据库集合以获得信息,如果当前会话ID不匹配则更新会话ID(并且可能强制用户重新认证?)等。

相关问题