我正在使用Web应用程序,需要我要求用户授予对其Google日历的访问权限(以便我可以代表他们阅读和创建活动)。
总结我的问题,请考虑oauth流程:
客户端(会话)-> 后端(会话)-> google (授予访问权限)-> 后端(我如何知道用户在这一步中存储了refresh_token?)
可能的虚拟解决方案:
客户端(会话)-> 后端(会话)-> google (授予访问权限)-> 客户端(会话)-> 后端(会话)
更多详细信息
这是默认流程:
const authUrl = new google.auth.OAuth2(clientId, secret, redirectUrl)).generateAuthUrl(options) res.redirect(authUrl)
这里是一个问题:我如何在“回调”中了解到该用户仍然是发起流程的同一用户?
这听起来可能很愚蠢,但我对此坚持不懈。
我知道会话应该可以解决该问题,但是由于“回调”是由Google的服务器触发的,并且是我的后端端点(而不是浏览器页面),因此除非我缺少某些内容,否则就没有会话。
据我了解,这是如何实现的,其中涉及首先重定向到浏览器:
但是,在客户端和后端之间来回进行所有操作似乎不是一个好方法
那么有没有一种方法可以在回调过程中标识用户,而无需在过程中间涉及浏览器?该怎么做?
我正在与nodejs合作,并在重要的时候表达意见
谢谢
答案 0 :(得分:0)
您应将刷新令牌保留在数据库中的服务器上。这是最安全的方法,可以防止攻击者通过网络访问刷新令牌并使用它来访问其帐户。
为用户创建一个ID,使用该ID映射到服务器上的客户端数据,例如刷新令牌。将该ID通过Cookie或JWT传递回浏览器和客户端。然后,每当用户向您的服务器发出请求时,他们将始终传递您在cookie中创建的ID。您可以使用该ID在数据库中查找用户并获取刷新令牌。
答案 1 :(得分:0)
尝试使用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);
}); } ));
答案 2 :(得分:0)
似乎有一个名为state
的参数,可以用来传递特定数据,Google会将其返回。因为我可以将用户ID或会话令牌作为状态传递并在回调中读取它,所以这解决了我的问题。
来自doc:
状态推荐。
指定应用程序要使用的任何字符串值 用于维护您的授权请求和 授权服务器的响应。服务器返回准确值 您在名称的散列(#)片段中以名称=值对的形式发送的 用户同意或拒绝您的应用程序后, 访问请求。
对于nodejs谷歌oauth2库,可能如下所示:
oauth2ClientGlobal.generateAuthUrl({
access_type: 'offline',
scope: this.scopes(),
state: base64UserId // <- google will return this param back
});