简体   繁体   English

OAuth2回调-识别用户?

[英]OAuth2 callback - identify user?

I'm working on web app where I need to ask user to grant access to their google calendar (so I can read and create events on their behalf). 我正在使用网络应用程序,需要我要求用户授予对其Google日历的访问权限(以便我可以代表他们阅读和创建活动)。

To summarize my question, consider the oauth flow: 总结一下我的问题,请考虑oauth流:

client (session) -> backend (session) -> google (grant access) -> backend (how do I know the user in this step to store the refresh_token?) 客户端 (会话)-> 后端 (会话)-> 谷歌 (授予访问权限)-> 后端 (我怎么知道用户在此步骤中存储refresh_token?)

Possible dummy solution: 可能的虚拟解决方案:

client (session) -> backend (session) -> google (grant access) -> client (session) -> backend (session) 客户端 (会话)-> 后端 (会话)-> Google (授予访问权限)-> 客户端 (会话)-> 后端 (会话)

More details 更多细节

Here is the default flow: 这是默认流程:

  • user logs in to my web app ( client ) 用户登录到我的Web应用程序( 客户端
  • the web app then asks the user to start oauth2 flow ( client ) 然后,Web应用程序要求用户启动oauth2流( 客户端
  • so user presses "start auth flow" button which sends "start auth flow" request to my backend ( client ) 因此用户按下“开始身份验证流程”按钮,该按钮会将“开始身份验证流程”请求发送到我的后端( 客户端
  • on the backend there is an oauth client that generates the request url and redirects user to that url ( backend ): 在后端,有一个oauth客户端,它生成请求url并将用户重定向到该url( backend ):
 const authUrl = new google.auth.OAuth2(clientId, secret, redirectUrl)).generateAuthUrl(options) res.redirect(authUrl) 
  • this redirects user to the google consent page. 这会将用户重定向到Google同意页面。 ( google ) 谷歌
  • Once user granted the permission, they are redirected back to the url specified in OAuth2 client ( backend , my "callback" endpoint) 用户授予权限后,它们将被重定向回OAuth2客户端( 后端 ,即我的“回调”端点)中指定的网址
  • at this point I need to save the refresh_token to the user's database location. 此时,我需要将refresh_token保存到用户的数据库位置。 ( backend ) 后端

And here is the question: how do I understand in the "callback" that this is still the same user who started the flow? 这里是一个问题:我如何在“回调”中了解到该用户仍然是发起流程的同一用户?

That might sound dumb, but I'm stuck with that. 这听起来可能很愚蠢,但我坚持这一点。

I understand that session should solve that, but since the "callback" is triggered by google's server and it's my backend endpoint (and not a browser page), there is no session unless I'm missing something. 我知道会话可以解决该问题,但是由于“回调”是由Google的服务器触发的,并且它是我的后端端点(而不是浏览器页面),因此除非我缺少某些内容,否则就没有会话。

In my understanding this is how it can be implemented which involves redirect to browser first: 以我的理解,这是如何实现的,其中涉及首先重定向到浏览器:

  • user logs in to my web app and I set the session cookie ( client ) 用户登录到我的Web应用程序,然后设置会话cookie( 客户端
  • user starts the oauth2 flow ( client/backend ) 用户启动oauth2流( 客户端/后端
  • the callback then redirects back to some dummy client-side page ( google ) 然后回调将重定向回一些虚拟的客户端页面( google
  • this dummy page extracts the auth code passed from google and sends it to my backend endpoint, passing the session along the way ( client ) 该虚拟页面提取从google传递的身份验证代码,并将其发送到我的后端端点,并一路传递会话( 客户端
  • now server knows who has performed the "callback" ( backend ) 现在服务器知道谁执行了“回调”( 后端

But that doesn't look like a good approach with all that back and forth between client and backend 但这似乎不是一种在客户端和后端之间来回往返的好方法

So is there a way to identify user during the callback without involving browser in the middle of the process? 那么,有没有一种方法可以在回调过程中标识用户,而无需在过程中间涉及浏览器? How to do that? 怎么做?

I'm working with nodejs and express in case that matters 我正在使用nodejs并表示重要

Thanks 谢谢

You should keep the refresh token on the server in a database. 您应该将刷新令牌保留在数据库中的服务器上。 This is the most secure way and prevents attacker from accessing the refresh token over the wire and using it to access their account. 这是最安全的方法,可以防止攻击者通过网络访问刷新令牌并使用它来访问其帐户。

Create an id for the user, use that id to map to client data on server such as refresh token. 为用户创建一个ID,使用该ID映射到服务器上的客户端数据,例如刷新令牌。 Pass that id back to the browser and client in cookies or JWT. 将该ID通过Cookie或JWT传递回浏览器和客户端。 Then, whenever user makes a request back to your server they will always pass that id you created in cookies. 然后,每当用户向您的服务器发出请求时,他们将始终传递您在cookie中创建的ID。 You can use that id to lookup the user in the database and get the refresh token. 您可以使用该ID在数据库中查找用户并获取刷新令牌。

Try using passportJs which provides authentication using third party authentication providers. 尝试使用使用第三方身份验证提供程序提供身份验证的passportJJ

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);
    });   } ));

It appeared that there is a parameter called state that one can use to pass specific data and google will return it back. 似乎有一个名为state的参数,可以用来传递特定数据,而google会将其返回。 This solves my question since I can pass user id or my session token as state and read it in the callback. 因为我可以将用户ID或会话令牌作为状态传递并在回调中读取它,所以这解决了我的问题。

From the doc : 文档

state Recommended. 状态推荐。

Specifies any string value that your application uses to maintain state between your authorization request and the authorization server's response. 指定应用程序用来维护授权请求和授权服务器的响应之间的状态的任何字符串值。 The server returns the exact value that you send as a name=value pair in the hash (#) fragment of the redirect_uri after the user consents to or denies your application's access request. 在用户同意或拒绝您的应用程序的访问请求之后,服务器会在redirect_uri的哈希(#)片段中返回您作为name = value对发送的确切值。

In case of nodejs google oauth2 library that may look like this: 如果是nodejs的Google oauth2库,可能看起来像这样:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 OAuth2和微服务:创建用户 - OAuth2 & Microservices : create an user Facebook OAuth2不提供用户电子邮件 - Facebook OAuth2 does not provide user email Passportjs的Google OAuth2回调引发无法访问此网站的错误 - PassportJs Google OAuth2 callback throws this site cant be reached error 使用 Firebase 函数的 Google oAuth2 回调问题 - Issue with Google oAuth2 callback using Firebase functions 在Heroku上获取Google OAuth2回调时的循环结构 - Circular structure when getting Google OAuth2 callback on Heroku OAuth2登录名哪个令牌提供用户详细信息,例如电子邮件,用户名 - OAuth2 Login Which Token gives User Details such as email, username 在 AWS Cognito Oauth2 令牌中包含用户详细信息 - Include user details in AWS Cognito Oauth2 token 如何使用oauth2检查用户在反应和表达中的身份验证,节点 - how to check user is authenticated in react and express, node using oauth2 启用MFA后如何使用oauth2来对广告身份验证用户进行Azure处理 - How azure ad auth user with oauth2 after enable MFA 如何安全地存储 Discord(OAuth2) 用户的访问令牌? - How to securely store the Access-Token of a Discord(OAuth2) User?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM