Google apps script 通过谷歌应用程序脚本安全地调用谷歌云功能
如何通过谷歌应用程序脚本安全地调用谷歌云功能 ✅ 我有一个谷歌云功能,我可以在Google apps script 通过谷歌应用程序脚本安全地调用谷歌云功能,google-apps-script,oauth,oauth-2.0,google-cloud-functions,google-oauth,Google Apps Script,Oauth,Oauth 2.0,Google Cloud Functions,Google Oauth,如何通过谷歌应用程序脚本安全地调用谷歌云功能 ✅ 我有一个谷歌云功能,我可以在https://MY_REGION-MY_PROJECT.cloudfunctions.net/MY_FUNCTION,我希望允许某些用户通过应用程序脚本调用它 ✅ 为了保护云函数的安全,我将云函数调用程序设置为只包含已知的电子邮件(例如USER@COMPANY.com,其中这是一封有效的谷歌电子邮件) ✅ 我能够通过curl成功地调用云函数,同时使用此电子邮件登录到gcloud,方法是运行:curlhttps://M
https://MY_REGION-MY_PROJECT.cloudfunctions.net/MY_FUNCTION
,我希望允许某些用户通过应用程序脚本调用它
✅ 为了保护云函数的安全,我将云函数调用程序设置为只包含已知的电子邮件(例如USER@COMPANY.com
,其中这是一封有效的谷歌电子邮件)
✅ 我能够通过curl成功地调用云函数,同时使用此电子邮件登录到gcloud,方法是运行:curlhttps://MY_REGION-MY_PROJECT.cloudfunctions.net/MY_FUNCTION -H“授权:持票人$(gcloud auth print identity token)”
✅ 我已在我的应用程序脚本的清单中授予以下OAuthScope:
”https://www.googleapis.com/auth/script.external_request“
”https://www.googleapis.com/auth/userinfo.email“
”https://www.googleapis.com/auth/cloud-platform“
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);
ℹ️ 我还尝试了以下方法:
- 使用
ScriptApp.getOAuthToken()
- 添加其他OAuthScope,例如
openid
- 使用
设置为授权的Javascript源代码https://script.google.com
- 部署应用程序脚本
- 绝望地向天空呼喊
- 你可以用。配额限制您每100分钟拨打16次电话(当然,这是为测试而设计的!)
- 您可以将邮件发布到和中。在这种模式中,您的调用是异步的
- 通过
(按说明)。如果这失败了,那么您会遇到与堆栈溢出问题不同的问题,所以我省略了这方面的故障排除步骤curl成功测试云功能的身份验证https://MY_REGION-MY_PROJECT.cloudfunctions.net/MY_FUNCTION -H“授权:持票人$(gcloud auth print identity token)”
- 确保你确实是。您无法从电子表格中的自定义函数获取标识令牌,因为它们是匿名运行的。在其他情况下,应用程序脚本代码可能作为其他人运行,例如某些触发器
- 如前所述重新部署云功能(或类似地,如前所述重新部署云运行容器),以便应用程序将拾取任何新的客户端ID配置。这是在创建任何新的客户端ID后需要的,包括通过向GCP项目添加或重新添加脚本自动创建的客户端ID。(如果将脚本移动到另一个GCP项目,然后再将其移回,则似乎会创建另一个客户端ID,而不是重用旧的客户端ID,旧的客户端ID将停止工作。)
- 添加(以及所有其他需要的作用域,例如
)在中明确显示https://www.googleapis.com/auth/script.external_request
将返回getIdentityToken()
,而不包含可能导致此错误的null
范围。读者注意:仔细阅读此要点-作用域名称字面上只是“openid
”-它不像其他作用域那样是URLopenid
"oauthScopes": ["openid", "https://...", ...]
- 使用和不使用
。根据我读到的内容,getOAuthToken()返回一个访问令牌,而不是标识令牌。访问令牌不能证明您的身份;相反,它们只是授予访问某些资源的权限getOAuthToken()
- 感谢您的评论,您可以做两件事。但在此之前,您必须知道,您不能(或者至少我从来没有做到这一点),创建一个有效的身份令牌,以便通过云功能进行身份验证,并使用用户凭据运行云
但您可以使用用户凭据调用Google Cloud API!所以
getIdentityToken
函数将返回一个仅对该客户端ID有效的身份令牌(它被编码到令牌字段中)。如果您想要为另一个项目工作的身份令牌,您需要以另一种方式获得
如果您能够将脚本和GCP功能或应用程序放在同一个GCP项目中,您还必须执行以下操作,其中许多操作您已经执行过:
async function callCloudFunction() {
const token = ScriptApp.getIdentityToken();
const options = {
headers: {'Authorization': 'Bearer ' + token}
}
const data = JSON.parse(await UrlFetchApp.fetch("https://MY_REGION-MY_PROJECT.cloudfunctions.net/MY_FUNCTION", options).getContentText())
return data
}