[英]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: 这是默认流程:
const authUrl = new google.auth.OAuth2(clientId, secret, redirectUrl)).generateAuthUrl(options) res.redirect(authUrl)
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: 以我的理解,这是如何实现的,其中涉及首先重定向到浏览器:
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或会话令牌作为状态传递并在回调中读取它,所以这解决了我的问题。
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.