是否可以使用 Google Apps 脚本项目的客户端机密文件从 Google 检索 OAuth2 访问令牌?

Is it possible to retrieve an OAuth2 access token from Google with client secret file of Google Apps Script project?

我想重用 Google Apps 脚本项目的 OAuth2 client-secret 以访问 Google APIs代表此脚本(例如,通过 Sheets API 读取脚本有权访问的电子表格)。拥有 Google 帐户的用户授予脚本必要的范围。现在我想用一个新的应用程序替换脚本,而无需再次征求用户的同意。通常,当脚本(或应用程序)运行时,用户会处于离线状态。

我的第一个问题是,如果这种情况是受支持的 OAuth2 use-case 和 Google API 授权,如果是这样,实现它的最佳方法是什么,特别是为了防止安全问题?

脚本的客户端机密

  1. OAuth2 client-secret 来自 Google API Console, under Credentials. Also see Credentials, access, security, and identity and Setting up OAuth 2.0
  2. 的脚本文件

client-secrets.json 看起来像这样:

{"web":{
"client_id": "57...1t.apps.googleusercontent.com",
"project_id": "project-id-95...70",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "K2...y1",
"redirect_uris": ["https://script.google.com/oauthcallback"]
}}

该文件将与应用程序代码 (App Engine) 一起部署。但是可以使用其他位置,例如 Cloud Storage。

OAuth2 访问令牌

在没有用户的情况下,我想使用与最初授予脚本相同范围的客户端 ID 和密码,从 Google 授权服务器获取访问令牌,例如这个:

HTTP 200 OK
Content-type: application/json
{
"access_token": "987tghjkiu6trfghjuytrghj",
"scope": "foo bar",
"token_type": "Bearer"
}

我想代表旧脚本使用 HTTP Bearer header 中的访问令牌来请求表格 API。

Client_credentials请求授权服务器

我(有限)的理解是,我可以使用 grant-type client_credentials 从授权服务器获取访问令牌。请求将如下所示:

POST /o/oauth2/token
Host: https://accounts.google.com
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Authorization: Basic Base_64_string

grant_type=client_credentials&
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fspreadsheets

其中基本 HTTP 授权是 client_id:client_secret 个值,以冒号分隔,并采用 base64 编码。

如果我在 body 中放弃 grant_typescope,我将得到相应的错误。

上述版本导致:{\n "error" : "invalid_request"\n} 响应,未提供具体信息。我已经尝试在 body 中使用 client_idclient_secret 结合和不结合授权 header,但都出现相同的错误。

首先让我先说我不是应用程序脚本或工作表方面的专家,我都用过几次,但我不认为自己是这方面的专家。

当您对某人进行身份验证时,他们的身份验证是根据项目中的客户端 ID 授予的。他们授予您访问其数据的权限并批准凭据请求。将其视为 Googles 数据库中某处的记录。

User 321 has granted consent to client 123 to access their sheets data.

所以您有一个项目 Super Script App,其客户端 ID 为 123,您正在请求访问编辑表。如果我批准,我将授予客户端 ID 为 123 的 Super Script App 访问我的工作表的权限。当我坐在我的机器前时,您的应用程序将 运行 访问我的数据。现在,当我注销客户端 ID 为 123 的 Super Script App 时,无法访问我的数据,除非您具有离线访问权限并具有刷新令牌。使用该刷新令牌,您将能够在我不在时通过请求新的访问令牌访问我的数据。

现在您想制作一个新应用。如果您使用客户端 ID 123 并在您的新应用程序中使用它,我将不得不登录到我的 google 帐户,但它不会弹出并请求我授予您访问我的数据的权限我已经授予客户端id 123 访问我的床单。除非你有刷新令牌,否则你将无法在没有我在场的情况下访问此数据。

如果您在任何时候要求额外的范围,我将不得不批准。

现在是有趣的部分。我已经有一段时间没有真正尝试过了。如果您转到 Google 开发人员控制台并在与客户端 ID 123 相同的项目下创建客户端 ID 321,然后在您的新 Super Script App V2 中使用它,我是否仍然需要授予它访问我的数据的权限?我可能不会倾向于。请注意,使用客户端 ID 123 创建的刷新令牌将无法与客户端 ID 321 一起使用,它们被锁定到客户端 除非它的移动设备并且它们的 .

有一些魔力

我不太确定你在用你的第二个应用程序做什么,所以我希望这有助于澄清问题。