Google OAuth 2.0 - 离线访问的增量授权

Rub*_*pez 1 oauth2-playground google-oauth google-api-js-client google-signin

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

首先,当用户登录时,应用程序会请求一些范围和离线访问。我正在生成刷新令牌并将其存储在数据库中,以便我可以刷新访问令牌以在需要时进行 API 调用。

现在,我将实现一个新功能,该功能将请求新范围,但只有当用户尝试使用此新功能时,我才会请求此范围。

我面临的问题是,当应用程序提示用户同意新范围时,Google 正在请求访问所有先前接受的范围。

我尝试过在没有离线访问的情况下(使用“授予”方法),它似乎有效(正如描述中所说的“向用户请求额外的范围”)。这样做,谷歌只是请求新的范围,并且生成的访问令牌似乎工作正常。但如果我尝试离线访问(使用“grantOfflineAccess”方法),Google 会要求提供所有范围。如果我再次接受所有范围,它会返回一个授权代码,我可以再次生成刷新令牌,但我想只接受新范围。

我想知道在请求离线访问时也许无法做到这一点,因为您需要生成一个具有所有范围的新刷新令牌,但我找不到任何有关此的信息。

我是否做错了什么,或者是否无法通过离线访问来实现此目的?

更新:同样生成 URL(而不是使用 JS 库),如此处所述 Google 要求提供所有范围。这是生成的 URL 的示例:

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
Run Code Online (Sandbox Code Playgroud)

UPDATE2:我在这里发现了一个报告的问题,有人评论说不可能对已安装的应用程序执行此操作。但有一条评论解释了如何使用 Web 服务器流执行此操作,这些是使用 OAuth2 Playground 的步骤(https://developers.google.com/oauthplayground):

1) 选择 Google 日历范围。

2) 授权访问

3)用代码交换令牌。

4) 向令牌信息端点发出请求: https://www.googleapis.com/oauth2/v2/tokeninfo?access_token = ...

5) 验证令牌是否仅包含 Google 日历范围。

6) 取消选择 Google Calendar 范围并选择 Google Drive 范围。

7) 在授权窗口中编辑 URL 并附加 &include_granted_scopes=true。

8) 授权Drive范围。

9) 将代码兑换为令牌。

10) 向令牌信息端点发出请求。

11) 验证它是否包含日历和云端硬盘范围。

执行相同的操作,我在第一次验证中获得日历范围,在第二次验证中获得驱动器范围。即使使用刷新令牌,我也无法获得两个范围的访问令牌。之后,这很奇怪,我检查了可以访问我的帐户的应用程序,并且 OAuth2 Playground 具有两个范围:

在此输入图像描述

先感谢您!

Rub*_*pez 5

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

因此,您只需发送新的范围,例如:

GoogleUser.grantOfflineAccess({scope: 'https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/calendar'}
Run Code Online (Sandbox Code Playgroud)

然后您将收到授权码以兑换refreshToken。您可以通过使用新的refreshToken生成access_token并调用令牌信息端点来检查一切是否正常:https: //www.googleapis.com/oauth2/v2/tokeninfo ?access_token = ...

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

无论如何,由于库的问题,我决定不使用增量授权。基本上问题是,为了获得更好的用户体验并避免出现问题,您应该能够使用,prompt: 'consent'以便用户不需要选择帐户来接受新范围。但这是不可能的,如果用户选择不同的帐户来接受应用程序中的不同范围,您可能会遇到问题。