我试图在我的应用程序中使用Google Oauth2实现增量授权。
起初,当用户登录时,应用程序正在请求一些范围和脱机访问。我正在数据库中生成和存储刷新令牌,以便在需要时刷新访问令牌以进行API调用。
现在我要实现一个新功能,它将请求一个新的作用域,但我只想在用户尝试使用这个新功能时请求这个作用域。
我面临的问题是,当应用程序提示用户同意新范围时,谷歌正在请求访问所有以前接受的范围。
我尝试过不使用脱机访问(使用“grant”方法),它似乎起到了作用(正如描述中所说的“向用户请求额外的作用域”)。这样一来,谷歌只需要申请新的作用域,生成的访问令牌似乎工作正常。但如果我尝试离线访问(使用“GrantofLeaceAccess”方法),谷歌会要求提供所有范围。如果我再次接受所有作用域,它会返回一个授权码,我可以再次生成refreshToken,但我只想接受新的作用域。
我想知道,当请求脱机访问时,可能无法执行此操作,因为您需要生成一个包含所有作用域的新refreshToken,但我找不到有关此操作的任何信息。
我是做错了什么,还是无法通过离线访问实现这一点?
更新:同样生成URL(而不是使用JS库),如本文所述,谷歌要求提供所有范围。这是生成的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
更新2:我在这里发现了一个报告中的问题,有人评论说,不可能对已安装的应用程序执行此操作。但是有一条注释解释了如何使用html" target="_blank">web服务器流,这些是使用OAuth2的步骤(https://developers.google.com/oauthplayground):
1) 选择谷歌日历范围。
2) 授权访问
3) 把代码换成令牌。
4)向令牌信息终结点发出请求:https://www.googleapis.com/oauth2/v2/tokeninfo?access_token=...
5) 验证令牌是否仅包含Google日历范围。
6)取消选择谷歌日历范围,选择谷歌驱动器范围。
7) 在授权窗口中编辑URL并附加
8)授权驱动器范围。
9)用代码交换令牌。
10) 向令牌信息endpoint发出请求。
11)验证它是否包含日历和驱动器范围。
做同样的事情,我在第一个验证中得到日历范围,在第二个验证中得到驱动范围。即使使用刷新令牌,我也无法获得两个范围的访问令牌。在那之后,这很奇怪,我检查了可以访问我的帐户的应用程序,OAuth2 playground有两个作用域:
提前谢谢!
谢谢,我也有同样的问题!你的回答帮助我弄明白了。下面是我们需要用两个库完成的最后一个工作流程。希望代码片段可能会有所帮助。
通过Google登录进行身份验证以获取刷新令牌
前端:
$('#signinButton').click(function() {
auth2.grantOfflineAccess().then(signInCallback);
});
后端:
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;
})
}
有了这个刷新令牌(您应该将其持久化),您可以随时使用googleapis库创建Google API的客户端。
实现增量授权
前端:
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}));
});
后端:
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 API与应用程序集成。查看带有节点的详细工作流。js后端,你可能会发现我的要点很有帮助。
我终于使用JS库实现了增量授权。使用grantoflineaccess函数,您可以发送想要请求的新作用域。默认情况下,当您使用gapi时,include_grated_scopes为true。auth2。批准
所以你只需要发送新的作用域,例如:
GoogleUser.grantOfflineAccess({scope: 'https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/calendar'}
然后,您将收到一个用于交换刷新令牌的授权码。通过使用新的refreshToken生成一个access_令牌并调用令牌信息endpoint,可以检查一切是否正常:https://www.googleapis.com/oauth2/v2/tokeninfo?access_token=...
我肯定这是我一开始试过的,所以我猜我做错了什么。
无论如何,由于库的问题,我决定不使用增量授权。基本上,问题是,为了更好的用户体验和避免问题,您应该能够使用提示:“同意”
,这样用户就不需要选择一个帐户来接受新的范围。但是这是不可能的,如果用户选择不同的帐户来接受应用程序的不同范围,您可能会遇到问题。
我试图使用VBScript和Oauth脱机访问谷歌日历API。我设法获得了一个刷新令牌和一个访问令牌,现在我想进入实际使用API的步骤,使用以下代码: 我得到的回应是: 即使访问令牌是有效的--如果我将sURL更改为https://www.googleapis.com/oauth2/v1/tokeninfo并运行该脚本,我将得到以下响应,显示一个有效的令牌: 如果我粘贴URL https://ww
我正在尝试使用Google OAuth2 api获取用户的配置文件。用户身份验证后,在同意页面上,我总是被要求“离线访问” 浏览器中的网址如下所示:- https://accounts.google.com/o/oauth2/auth?scope=email 如上面的URL中可见,我已将范围参数传递为“电子邮件” Google Auth API页面说:- “此范围要求您的应用程序能够访问: 用户的
我正在使用<code>Microsoft.Owin.Security。Google(版本)middlware为我的应用程序提供Google OAuth。 它的配置如下: 非常简单的东西。我使用身份服务器作为MW来发出声明。 这是完全有意义的,因为我在URL中请求作用域: https://accounts.google.com/o/oauth2/auth?scope=openid简介邮件 然后我接受
这是我之前问题的后续:如何从远程服务器访问Google Drive应用程序数据? 我有一个需要访问Google Drive AppFolder的应用程序,包括客户端(在线、JavaScript)和服务器端(离线、Python)。我的应用程序是独一无二的,因为客户端和服务器可能无法通过原始身份验证进行通信。 因此,我使用下面的代码来获取服务器的auth令牌(启动客户端): 服务器存储包括刷新令牌在内
我正在尝试使用Google API获得<code>离线访问</code>。我必须从谷歌日历中提取数据,而无需用户每次登录。 我已将以下内容添加到我的 Gem 文件中: https://accounts.google.com/o/oauth2/auth?access_type=offline 我错过什么了吗?
问题内容: 我正在为基于Web的幻灯片显示构建应用程序,其中一个“主”用户可以在幻灯片之间移动,每个人的浏览器都可以跟随。为此,我使用websockets和Redis作为全局通道来发送消息。每个连接的客户端都将信息存储在数组中。然后,我有一个单独的线程用于订阅Redis通道,其中定义了一个“ on.message”块,该块应将消息发送给数组中的每个人,但是该数组在此块内为空(在该块中的其他任何地方