google-app-engine - 如何通过 Apps 脚本验证服务帐户以调用 GCP 云功能
问题描述
我正在努力从 Apps 脚本运行 GCP 云功能。云功能需要身份验证。但是我一直被抛出“401错误”
在我的谷歌项目上;
- 我创建了一个需要身份验证的云功能
- 我已经创建了一个具有调用(和编辑)该功能访问权限的服务帐户
- 我已下载该服务帐户的 JSON 密钥并将其保存为我的 Apps 脚本中名为CREDS的对象
到目前为止,这是我的脚本:
const CREDS = {....JSON Key I downloaded from Cloud Console}
function base64Encode(str){
let encoded = Utilities.base64EncodeWebSafe(str)
return encoded.replace(/=+$/,'')
}
function encodeJWT(){
const privateKey = `Copied the PK from the CREDs file and replaced all the escaped whitespace as a string literal`;
let header = JSON.stringify({
alg: "RS256",
typ: "JWT",
});
let encodedHeader = base64Encode(header);
const now = Math.floor(Date.now() / 1000);
let payload = JSON.stringify({
"iss": "https://accounts.google.com",
"azp": "OAUTH CLIENT ID I CREATED ON GCP",
"aud": "OAUTH CLIENT ID I CREATED ON GCP",
"sub": CREDS.client_id,
"email": CREDS.client_email,
"email_verified": true,
// "at_hash": "TMTv8_OtKA539BBRxLoTBw", //Saw this in a reverse engineered Token but didnt know what to put
"iat": now.toString(),
"exp": (now + 3600).toString()
})
let encodedPayload = base64Encode(payload);
let toSign = [encodedHeader, encodedPayload].join('.')
let signature = Utilities.computeRsaSha256Signature(toSign, privateKey)
let encodedSignature = base64Encode(signature);
let jwt = [toSign, encodedSignature].join('.')
return jwt;
}
function testFireStore() {
let funcUrl = "https://[MY PROJECT].cloudfunctions.net/MyFunc"
const token = encodeJWT()
let options = {
headers:{
"Authorization": "Bearer " + token
}
}
let func = UrlFetchApp.fetch(funcUrl,options)
Logger.log(func.getContentText())
}
实际的 Cloud func 现在只给出一个“Hello World”,它在控制台中测试良好
仅供参考,我已经完成了一些步骤
- 我在本地机器上使用 gcloud 生成了一个令牌,并在我的应用程序脚本中使用它,效果很好
- 我已经使用了上述令牌并在https://jwt.io上对其进行了逆向工程
- 我使用此处的代码创建了我的 JWT 函数,我使用https://jwt.io进行了检查,以确保其格式正确。
解决方案
@TheMaster 在我的解决方案的评论中发布的这个解决方案解决了这个问题。
在 GCP 方面,我进入并启用了计算引擎和 App Engine,然后使用了这个解决方案并且它起作用了。
唯一奇怪的是target_audience在那里请求,我必须做一些逆向工程才能得到它。我必须从命令行工具获取身份令牌,然后使用 jwt.io 对其进行解码,获取 AUD 密钥...
但除此之外,一切都像一个魅力
推荐阅读
- javascript - 专注于 jquery 数据表的行并在重点行上按 enter 键应该将行传递到另一个数据表
- python - 为什么只打印第一项
- c++ - 优先队列未正确排序
- javascript - 为什么 svg 加载仅在 Google Chrome 中延迟
- c# - 如何从现有列表中获取与关键字匹配并忽略大小写的项目列表(不区分大小写)?
- python - 时间乘法矩阵和向量
- r - 如何让 R 将这些单元格读取为空白而不是 NA?
- ruby - ruby 编码有什么问题?
- openssl - 通过 HTTPS 为 NiFi 生成自签名证书
- mysql - MySQL 一对多关系将值从一个表添加到另一个表