我了解到我的应用程序需要一个刷新令牌,但是我不想编写代码来获取它,因为我只需要这样做一次。
注意:这不是使用服务账号。该应用程序将在常规Google账户下运行。服务账户是某些情况下的有效方法。然而,使用Oauth Playground模拟应用程序的技巧可以节省大量冗余工作,并适用于任何不支持向服务账户共享的API。
NB June 2022. Google已更新其验证要求,添加了额外的步骤(或根据您的观点取消了该方法)。有关更多详细信息,请参见最近的评论。
可以使用Oauth2 Playground在https://developers.google.com/oauthplayground上完成此操作。
步骤如下:
Credentials/Create Credentials/OAuth Client Id
然后选择Web application
现在,您的应用程序可以无人值守运行,并使用Refresh Token,如https://developers.google.com/accounts/docs/OAuth2WebServer#offline所述,获取访问令牌。
NB. 请注意,Google可能会使刷新令牌过期,这意味着您需要重复执行步骤5以后的步骤以获取新的刷新令牌。如果您尝试使用刷新令牌时返回Invalid Grant,则这是其症状。
NB2. 如果您想要一个访问您自己(且只有您自己)Drive帐户的Web应用程序,而不必编写授权代码(只会运行一次),则此技术非常有效。跳过步骤1,在步骤6中将“my.drive.app”替换为您自己的电子邮件地址。请确保您了解如果Refresh Token被盗取的安全性问题。
请参见下面Woody的评论,他链接到此Google视频https://www.youtube.com/watch?v=hfWe1gPCnzc
function get_access_token_using_saved_refresh_token() {
// from the oauth playground
const refresh_token = "1/0PvMAoF9GaJFqbNsLZQg-f9NXEljQclmRP4Gwfdo_0";
// from the API console
const client_id = "559798723558-amtjh114mvtpiqis80lkl3kdo4gfm5k.apps.googleusercontent.com";
// from the API console
const client_secret = "WnGC6KJ91H40mg6H9r1eF9L";
// from https://developers.google.com/identity/protocols/OAuth2WebServer#offline
const refresh_url = "https://www.googleapis.com/oauth2/v4/token";
const post_body = `grant_type=refresh_token&client_id=${encodeURIComponent(client_id)}&client_secret=${encodeURIComponent(client_secret)}&refresh_token=${encodeURIComponent(refresh_token)}`;
let refresh_request = {
body: post_body,
method: "POST",
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
})
}
// post to the refresh endpoint, parse the json response and use the access token to call files.list
fetch(refresh_url, refresh_request).then( response => {
return(response.json());
}).then( response_json => {
console.log(response_json);
files_list(response_json.access_token);
});
}
// a quick and dirty function to list some Drive files using the newly acquired access token
function files_list (access_token) {
const drive_url = "https://www.googleapis.com/drive/v3/files";
let drive_request = {
method: "GET",
headers: new Headers({
Authorization: "Bearer "+access_token
})
}
fetch(drive_url, drive_request).then( response => {
return(response.json());
}).then( list => {
console.log("Found a file called "+list.files[0].name);
});
}
get_access_token_using_saved_refresh_token();
警告:2022年5月 - 此答案可能已过时 - 请查看David Stein的评论
让我给pinoyyid的优秀答案添加一条替代路线(对我来说没有用-弹出重定向错误)。
您不必使用OAuthPlayground,而是可以直接使用HTTP REST API。因此,与pinoyyid的答案不同,我们将在本地执行操作。按照pinoyyid的答案中的步骤1-3。我将引用它们:
现在,不要使用playground,在凭据中添加以下内容:
授权的JavaScript源:http://localhost(我不知道是否需要,但只需这样做。)
授权重定向URI:http://localhost:8080
屏幕截图(德语):
确保通过下面的蓝色按钮实际保存更改!
现在,您可能需要使用GUI构建HTTP请求。我使用了Insomnia,但您可以选择Postman或纯cURL。我推荐Insomnia,因为它可以让您轻松地通过同意屏幕。
使用以下参数构建新的GET请求:
URL: https://accounts.google.com/o/oauth2/v2/auth
Query Param: redirect_uri=http://localhost:8080
Query Param: prompt=consent
Query Param: response_type=code
Query Param: client_id=<your client id from OAuth credentials>
Query Param: scope=<your chosen scopes, e.g. https://www.googleapis.com/auth/drive.file>
Query Param: access_type=offline
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('ok');
console.log(req)
});
app.listen(8080, function () {
console.log('Listening on port 8080!');
});
通过 node index.js
运行服务器。我建议要么不记录整个 req
对象,要么运行 node index.js | less
,因为完整的输出将会非常巨大。
其他语言也有非常简单的解决方案。例如,在8080端口上使用 PHP 内置的 Web 服务器:php -S localhost:8080
。
现在,在 Insomnia 中发送您的请求,您应该会看到登录提示:
使用您的电子邮件和密码登录,然后确认同意屏幕(应包含您选择的范围)。
返回您的终端并检查输出。如果记录了整个内容,请滚动到底部(例如在 less 中按 PgDn),直到看到一行带有 code=4/...
的代码。
复制该代码;这是您要交换访问令牌和刷新令牌的授权代码。不要复制太多-如果有一个 & 符号,请不要复制它或之后的任何内容。& 符号分隔查询参数。我们只需要code
。
现在设置一个 HTTP POST 请求,指向 https://www.googleapis.com/oauth2/v4/token
作为 表单 URL 编码。在 Insomnia 中,您只需单击即可完成-在其他工具中,您可能需要自己设置标题为 Content-Type: application/x-www-form-urlencoded
。
添加以下参数:
code=<the authorization code from the last step>
client_id=<your client ID again>
client_secret=<your client secret from the OAuth credentials>
redirect_uri=http://localhost:8080
grant_type=authorization_code
再次确保编码正确。
发送请求并检查来自服务器的输出。您应该看到一个JSON对象:
{
"access_token": "xxxx",
"expires_in": 3600,
"refresh_token": "1/xxxx",
"scope": "https://www.googleapis.com/auth/drive.file",
"token_type": "Bearer"
}
您可以立即使用access_token
,但它仅在一个小时内有效。请注意刷新令牌。这是您始终可以*用于交换新的访问令牌的令牌。
*
如果用户更改密码、撤销访问权限、处于不活动状态超过6个月等,则必须重复该过程。
祝您OAuth愉快!