zac*_*din 10 oauth google-apps-script oauth-2.0 google-oauth google-cloud-functions
如何通过 Google Apps 脚本安全地调用 Google Cloud Function?
? 我有一个谷歌云函数,我可以访问https://MY_REGION-MY_PROJECT.cloudfunctions.net/MY_FUNCTION
它,我想允许某些用户通过应用程序脚本调用。
? 为了保护云功能,我已将云功能调用程序设置为仅包含已知电子邮件(例如USER@COMPANY.com
,这是有效的 Google 电子邮件)。
? 我能够通过卷曲成功地调用云功能,在登录到gcloud与此电子邮件,通过运行:curl https://MY_REGION-MY_PROJECT.cloudfunctions.net/MY_FUNCTION -H "Authorization: Bearer $(gcloud auth print-identity-token)"
。
? 我已在我的 Apps 脚本清单中授予以下 oauthScopes:
"https://www.googleapis.com/auth/script.external_request"
"https://www.googleapis.com/auth/userinfo.email"
"https://www.googleapis.com/auth/cloud-platform"
?? 但是,当我尝试通过 Google Apps 脚本调用云函数时,在使用电子邮件登录时USER@COMPANY.com
,我无法调用它,而是返回了 401。这是我尝试调用云函数的方法:
const token = ScriptApp.getIdentityToken();
const options = {
headers: {'Authorization': 'Bearer ' + token}
}
UrlFetchApp.fetch("https://MY_REGION-MY_PROJECT.cloudfunctions.net/MY_FUNCTION", options);
Run Code Online (Sandbox Code Playgroud)
?? 我还尝试了以下方法:
ScriptApp.getOAuthToken()
openid
.https://script.google.com
并将其设置为授权的 Javascript 来源。Ale*_*lor 16
我在通过 Apps Script 进行身份验证以调用 Cloud Run 应用程序时遇到了很多困难,然后才弄清楚,我相信调用任何 Google Cloud 应用程序(包括 Cloud Functions)都是类似的。本质上,目标是使用您已经以用户身份运行 Apps 脚本的身份验证信息调用受Google Cloud IAM保护的 HTTP 方法。
我认为缺少的一步是,您使用的技术仅在 Apps Script 脚本和 Google Cloud Function(或在我的情况下运行容器)在同一个 GCP 项目中时才有效。(查看如何将脚本与 GCP 项目相关联。)
以这种方式进行设置比其他方式简单得多:当您将脚本与 GCP 项目相关联时,这会自动为项目创建OAuth 客户端 ID配置,并且 Apps 脚本的getIdentityToken
函数返回仅对该客户端 ID 有效的身份令牌(它被编码到令牌的aud
字段字段中)。如果您想要一个适用于另一个项目的身份令牌,则需要另一种方式。
如果您能够将脚本和 GCP 函数或应用程序放在同一个 GCP 项目中,那么您还必须做这些事情,其中许多事情您已经做过:
通过curl https://MY_REGION-MY_PROJECT.cloudfunctions.net/MY_FUNCTION -H "Authorization: Bearer $(gcloud auth print-identity-token)"
(按照此处的说明)成功测试您的云功能的身份验证。如果这失败了,那么您遇到的问题与此 Stack Overflow 问题中所问的问题不同,因此我省略了对此的故障排除步骤。
确保您实际上是脚本运行的人。您无法从电子表格中的自定义函数中获取身份令牌,因为它们是匿名运行的。在其他情况下,Apps 脚本代码可能会以其他人的身份运行,例如某些触发器。
重新部署如所提到的云功能这里(或类似地如所提到的重新部署云中运行容器此处),因此该应用将拿起任何新客户端ID的配置。创建任何新客户端 ID 后都需要这样做,包括通过向 GCP 项目添加或重新添加脚本而自动创建的客户端 ID。(如果您将脚本移动到另一个 GCP 项目,然后再将其移回,它似乎创建了另一个客户端 ID,而不是重复使用旧的,旧的将停止工作。)
在清单中显式添加" openid
" 范围(以及所有其他需要的范围,例如https://www.googleapis.com/auth/script.external_request
)。将在没有可能导致此错误的范围的情况下返回。读者注意事项:请仔细阅读此要点 - 范围名称实际上只是“ ” - 它不像其他范围那样是一个 URL。getIdentityToken()
null
openid
openid
"oauthScopes": ["openid", "https://...", ...]
Run Code Online (Sandbox Code Playgroud)使用getIdentityToken()
和不使用getOAuthToken()
。根据我读过的内容, getOAuthToken() 返回访问令牌而不是身份令牌。访问令牌不能证明您的身份;相反,他们只是提供访问某些资源的证明授权。
如果您无法将脚本添加到与 GCP 应用程序相同的项目中,我不知道该怎么做,因为我从未成功尝试过。通常,您的任务是获取与您的 GCP 客户端 ID 之一相关联的 OAuth 身份令牌。我不认为一个应用程序(或 GCP 项目)应该能够为不同的 OAuth 应用程序(不同的 GCP 项目)获取身份令牌。不管怎样,还是有可能的。Google 在其OpenID Connect 文档中从高层次讨论了 OAuth 身份验证。也许是使用Web 客户端执行常规Google 登录流程的HTML 服务,如果您让用户单击重定向链接,因为 Apps 脚本不允许浏览器重定向,则适用于用户存在的操作。如果您只需要保护您的服务不受公众影响,也许您可以尝试其他涉及服务帐户的身份验证选项。(我也没有尝试过。)如果服务只需要知道用户是谁,也许您可以解析身份令牌并将用户的标识符作为请求的一部分发送。如果服务需要访问他们的 Google 资源,那么也许您可以让用户单独登录到该应用程序,并通常使用 OAuth 来长期访问他们的资源,在 Apps 脚本调用时根据需要使用它。
感谢您的评论,您可以做两件事。但在此之前,您必须知道您无法(或者至少我从未实现过这一点)创建一个有效的身份令牌,以便由 Cloud Function 和 Cloud Run 使用用户凭证进行身份验证。我对此提出了一个问题
但您可以使用用户凭证调用 Google Cloud API!所以
归档时间: |
|
查看次数: |
1681 次 |
最近记录: |