首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >谷歌OAuth 2.0 -具有离线访问的增量授权

谷歌OAuth 2.0 -具有离线访问的增量授权
EN

Stack Overflow用户
提问于 2018-07-24 09:24:21
回答 2查看 2.2K关注 0票数 1

我正在尝试在我的应用程序中使用Google Oauth2来实现增量授权

首先,当用户登录时,应用程序将请求某些作用域和脱机访问。我正在数据库中生成和存储refreshToken,以便在需要时刷新访问令牌以进行API调用。

现在,我将实现一个新的功能,它将请求一个新的作用域,但是只有当用户尝试使用这个新功能时,我才会请求这个作用域。

我面临的问题是,当应用程序促使用户同意新的作用域时,Google请求所有以前接受的作用域的访问权限。

我尝试过不使用离线访问(使用“授予”法),而且它似乎正在工作(正如描述中所说的“向用户请求附加作用域”)。这样做,Google只要求新的范围,生成的访问令牌似乎运行良好。但是如果我尝试使用离线访问(使用“grantOfflineAccess”方法),谷歌会询问所有的作用域。如果我再次接受所有的作用域,它将返回一个授权代码,并且我可以再次生成refreshToken,但是我只想接受新的作用域。

我想知道在请求离线访问时不可能这样做,因为您需要生成一个包含所有作用域的新refreshToken,但是我找不到有关这方面的任何信息。

我是否做错了什么,还是不可能通过离线访问实现这一点?

UPDATE:也生成(而不是使用JS库),解释了这里,它要求所有的作用域。这将是生成URL的一个示例:

代码语言:javascript
运行
复制
https://accounts.google.com/o/oauth2/v2/auth?
  scope=my_new_scope&
  redirect_uri=https://myapp.example.com/callback&
  response_type=code&
  client_id=my_client_id&
  prompt=consent&
  include_granted_scopes=true

UPDATE2:我找到了一个这里报道的问题,有人评论说在安装的应用程序中不可能这样做。但是有一条评论解释了如何使用web服务器流来实现它,下面是使用OAuth2游乐场(https://developers.google.com/oauthplayground)的步骤:

1)选择作用域。 2)授权进入 3)令牌的交换代码。 4)请求令牌信息端点:token=. 5)验证令牌只包含作用域。 6)取消选择作用域并选择Google作用域。 7)在授权窗口中编辑URL并附加&include_granted_scopes=true。 8)授权驾驶范围。 9)将代码交换为令牌。 10)向令牌信息端点发出请求。 11)验证它是否包含日历和驱动器作用域。

同样,我在第一个验证中获得日历作用域,在第二个验证中获得驱动范围。即使使用刷新令牌,我也无法获得两个作用域的访问令牌。在此之后,非常奇怪的是,我检查了访问我的帐户的应用程序,OAuth2操场有两个作用域:

提前谢谢你!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-02 17:38:28

我终于完成了使用JS库实现增量授权。使用grantOfflineAccess函数,您可以发送要请求的新范围。默认情况下,当使用include_granted_scopes时,gapi.auth2.authorize是正确的。

所以您只需要发送新的作用域,例如:

代码语言:javascript
运行
复制
GoogleUser.grantOfflineAccess({scope: 'https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/calendar'}

然后,您将收到一个用于交换refreshToken的授权代码。您可以通过使用新的access_token生成一个refreshToken并调用令牌信息端点:token=.

我肯定这是我一开始尝试过的事情,所以我想我做错了什么。

无论如何,由于图书馆的问题,我决定不使用增量授权。基本上问题是,为了获得更好的用户体验和避免问题,您应该能够使用prompt: 'consent',这样用户就不需要选择帐户来接受新的作用域。但这是不可能的,如果用户选择不同的帐户来接受应用程序中的不同作用域,则可能会出现问题。

票数 5
EN

Stack Overflow用户

发布于 2021-06-20 19:18:13

谢谢,我也有同样的问题!你的答案帮我解决了这个问题。下面是我们需要用两个库完成的最终工作流。希望这些代码片段可能会有所帮助。

  1. 使用Google登录(google-auth图书馆)进行身份验证以获得刷新令牌。
  2. 实现增量授权:授权应用程序使用他们的信息将其与新的Google集成。例如,Google (google-auth图书馆谷歌越界)

使用Google登录进行身份验证,以获得刷新令牌

前端:

代码语言:javascript
运行
复制
$('#signinButton').click(function() {
   auth2.grantOfflineAccess().then(signInCallback);
 });

后端:

代码语言:javascript
运行
复制
const { OAuth2Client } = require('google-auth-library');

/**
* Create a new OAuth2Client, and go through the OAuth2 content
* workflow. Return the refresh token.
*/
function getRefreshToken(code, scope) {
  return new Promise((resolve, reject) => {
    // Create an oAuth client to authorize the API call. Secrets should be 
    // downloaded from the Google Developers Console.
    const oAuth2Client = new OAuth2Client(
      YOUR_CLIENT_ID,
      YOUR_CLIENT_SECRET,
      YOUR_REDIRECT_URL
    );

    // Generate the url that will be used for the consent dialog.
    await oAuth2Client.generateAuthUrl({
      access_type: 'offline',
      scope,
    });
    
    // Verify the integrity of the idToken through the authentication 
    // code and use the user information contained in the token
    const { tokens } = await client.getToken(code);
    const ticket = await client.verifyIdToken({
      idToken: tokens.id_token!,
      audience: keys.web.client_secret,
    });
    idInfo = ticket.getPayload();
    return tokens.refresh_token;
  })
}

有了这个刷新令牌(您应该持久化它),您可以随时使用谷歌越界库创建Google的客户端。

实现增量授权

前端:

代码语言:javascript
运行
复制
const googleOauth = gapi.auth2.getAuthInstance();
const newScope = "https://www.googleapis.com/auth/calendar"

googleOauth = auth2.currentUser.get();
googleOauth.grantOfflineAccess({ scope: newScope }).then(
    function(success){
      console.log(JSON.stringify({ message: "success", value: success }));
    },
    function(fail){
      alert(JSON.stringify({message: "fail", value: fail}));
    });

后端:

代码语言:javascript
运行
复制
const { google } = require('googleapis'); 

// Create an oAuth client to authorize the API call. Secrets should be 
// downloaded from the Google Developers Console.
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

client.setCredentials({ refresh_token: refreshToken });

就这样!您可以使用此客户端将任何Google与您的应用程序集成。对于带有Node.js后端的详细工作流,您可能会发现我的精神很有帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51495056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档