【问题标题】:OAuth2 callback - identify user?OAuth2 回调 - 识别用户?
【发布时间】:2019-04-28 17:51:33
【问题描述】:

问题:当我使用 oauth2(从我的服务器启动)对用户进行身份验证时,如何从 oauth2 回调中获取初始用户 ID,以便将其映射回初始身份验证请求在我的服务器上?

上下文:

我正在开发一个网络应用程序,我需要在其中要求用户授予对其 Google 日历的访问权限。

考虑 oauth 流程:

web 客户端(发送请求到)-> backend(发送 oauth 请求到)-> google(授予访问权限)-> backend(这一步怎么知道用户存储refresh_token?)

这里是更多细节默认流程:

  • 用户登录到我的网络应用(客户端
  • 网络应用要求用户启动 oauth2 流(客户端
  • 将“启动身份验证流程”请求发送到我的后端(后端
  • 在后端,我向 google 发送 oauth 请求,如下所示:
const authUrl = new google.auth.OAuth2(clientId, secret, redirectUrl)).generateAuthUrl(options)
res.redirect(authUrl)
  • 这会将用户重定向到谷歌同意页面。 (谷歌
  • 一旦用户授予权限,他们将被重定向回 OAuth2 客户端中指定的 url(后端,我的“回调”端点)
  • 此时我需要将 refresh_token 保存到用户的数据库位置。 (后端

那么我如何从“回调”中理解这仍然是启动流程的同一用户?

【问题讨论】:

  • 为什么需要跟踪用户在流程中的位置? AFAIK真的没有办法做到这一点。获得访问令牌后,您还应该收到有关刚刚授予访问权限的人的一些基本个人资料信息。
  • @MikeWilcox - 我只需要为该特定用户存储“refresh_token”。你将如何做到这一点?关于基本信息 - 如果我没记错的话,您说的是 google 帐户信息(如电子邮件、google id?),这与用户在注册我的应用程序时提供的信息不一定相同(他们可以使用不同的电子邮件地址注册为与他们用来授予权限的谷歌帐户相反的帐户,因此我不能使用它来匹配两者)。

标签: node.js express google-oauth


【解决方案1】:

似乎有一个名为state 的参数可以用来传递特定数据,谷歌会将其返回。这解决了我的问题,因为我可以将用户 ID 或会话令牌作为状态传递并在回调中读取。

来自doc

状态推荐。

指定您的应用程序的任何字符串值 用于维护您的授权请求和 授权服务器的响应。服务器返回准确值 您在 在用户同意或拒绝您的应用程序之后的 redirect_uri 访问请求。

如果是 nodejs google oauth2 库,可能如下所示:

oauth2ClientGlobal.generateAuthUrl({
            access_type: 'offline',
            scope: this.scopes(),
            state: base64UserId // <- google will return this param back
        });

【讨论】:

    【解决方案2】:

    您应该将服务器上的刷新令牌保存在数据库中。这是最安全的方法,可以防止攻击者通过网络访问刷新令牌并使用它来访问他们的帐户。

    为用户创建一个 id,使用该 id 映射到服务器上的客户端数据,例如刷新令牌。在 cookie 或 JWT 中将该 id 传递回浏览器和客户端。然后,每当用户向您的服务器发出请求时,他们总是会传递您在 cookie 中创建的 id。您可以使用该 id 在数据库中查找用户并获取刷新令牌。

    【讨论】:

    • 谢谢迈克。是的,这基本上就是我想要做的 - 将刷新令牌存储在服务器上。问题是如何做到这一点,只要来自谷歌的“回调”不包含用户的任何标识符(例如存储在我的系统或注册电子邮件中的用户 ID),以便我可以使用它并保存令牌对于该特定用户。问题是,预期的流程 - 用户从浏览器启动 oauth,最后我将刷新令牌存储在该用户的服务器上。但我不知道如何实现这一点,因为我无法在“回调”中识别用户。有什么想法吗?
    【解决方案3】:

    尝试使用passportJs,它使用第三方身份验证提供商提供身份验证。

    var GoogleStrategy = require( 'passport-google-oauth2' ).Strategy;
    
    passport.use(new GoogleStrategy({
        clientID:     GOOGLE_CLIENT_ID,
        clientSecret: GOOGLE_CLIENT_SECRET,
        callbackURL: "http://yourdormain:3000/auth/google/callback",
        passReqToCallback   : true   },   function(request, accessToken, refreshToken, profile, done) {
        User.findOrCreate({ googleId: profile.id }, function (err, user) {
          return done(err, user);
        });   } ));
    

    【讨论】:

    • 感谢您的建议。问题更多是关于 oauth2 的基础知识,我似乎遗漏或误解了这些基础知识。人们如何识别回调身份,即谁发出了初始请求?到目前为止,似乎只能涉及客户端和某种会话。
    • 在回调函数中收到请求参数,其中包含原始请求参数,可用于区分不同的请求。
    • 天哪,非常感谢!您的评论使我想到了这个问题,它基本上解决了我的问题:stackoverflow.com/questions/7722062/…。如果您可以将您的评论作为答案发布,我将接受它作为正确标记此问题已解决
    猜你喜欢
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 2018-10-08
    • 2019-02-03
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多