我在Google Cloud Functions上运行了一个HTTP触发的功能,该功能使用require('googleapis').sheets('v4')
将数据写入文档电子表格。
对于本地开发,我通过其开发者控制台的Service Accounts部分添加了一个帐户。我下载了令牌文件(下面是dev-key.json)并用它来验证我对Sheets API的请求,如下所示:
var API_ACCT = require("./dev-key.json");
let apiClient = new google.auth.JWT(
API_ACCT.client_email, null, API_ACCT.private_key,
['https://www.googleapis.com/auth/spreadsheets']
);
exports.myFunc = function (req, res) {
var newRows = extract_rows_from_my_client_app_request(req);
sheets.spreadsheets.values.append({
auth: apiClient,
// ...
resource: { values:newRows }
}, function (e) {
if (e) res.status(500).json({err:"Sheets API is unhappy"});
else res.status(201).json({ok:true})
});
};
用我的服务帐户的“电子邮件地址”分享我的电子表格后,例如local-devserver@foobar-bazbuzz-123456.iam.gserviceaccount.com
- 它有效!
但是,当我将其部署到Google Cloud Functions服务时,我想知道是否有更好的方法来处理凭据?我的代码可以自动进行身份验证,而无需将JWT密钥文件与部署捆绑在一起吗?
我注意到我的函数运行时设置了FUNCTION_IDENTITY=foobar-bazbuzz-123456@appspot.gserviceaccount.com
个环境变量,但我不知道如何在我的googleapis调用的auth
值中使用它。 code for google.auth.getApplicationDefault
不使用它。
上传私有JWT令牌和我的GCF代码是否可行?或者我应该以某种方式使用metadata server吗?或者,云功能是否已经可以通过内置方式对其他Google API进行身份验证?
答案 0 :(得分:4)
将凭证与功能部署捆绑在一起很常见。只是不要将它们检查到源代码管理中。 Cloud Functions for Firebase samples在需要时执行此操作。例如,从云存储创建签名URL需要管理员凭据,this sample说明将该凭据保存到要与这些功能一起部署的文件中。
答案 1 :(得分:1)
我想知道是否有更好的方式来处理凭据?我可以吗 代码会自动进行身份验证,而无需捆绑JWT 密钥文件与部署有关?
是的。您可以使用“ Application Default Credentials”代替执行此操作的方法,但是不要使用函数getApplicationDefault(),因为自发布此Q以来,该函数已被弃用。
上面的链接显示了如何使用google.auth.getClient API进行简单调用,提供所需的范围,并让它自动确定所需的凭据类型。在云端功能上,这将是google-auth-library中定义的“计算”对象。
这些文档说得很好here ...
设置服务帐户后,ADC可以隐式找到您的 凭据,无需更改您的代码,如 以上部分。
其中ADC是应用程序默认凭据。
请注意,对于Cloud Functions,请使用App Engine服务帐户: YOUR_PROJECT_ID@appspot.gserviceaccount.com,为documented here。那是您通过FUNCTION_IDENTITY env var找到的那个-这真让我绊倒了。
最后一步是确保服务帐户具有与电子表格相同的访问权限。