我有一个 firebase 功能,我想允许对云存储进行写访问。我相信我需要设置一个具有这些权限的服务帐户,然后在我的函数中以编程方式授予它们,但我很困惑如何做到这一点。
firebase 函数将文件写入触发器上的存储桶。Firebase 存储的存储设置设置为默认值,这意味着它们需要对客户端进行身份验证:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
在本文档(https://cloud.google.com/functions/docs/concepts/iam)中,在“运行时服务帐户”下,我看到:
在运行时,Cloud Functions 使用服务帐户 PROJECT_ID@appspot.gserviceaccount.com,该帐户在项目中具有编辑者角色。您可以更改此服务帐户的角色以限制或扩展您正在运行的函数的权限。
当它说“运行时”时,我假设这意味着 firebase 函数在该服务帐户的上下文中运行,并且授予它权限。因此,我假设我需要确保该服务帐户的权限具有写入权限,正如我从这个链接中看到的那样(https://console.cloud.google.com/iam-admin/roles?authuser=0&consoleUI =FIREBASE&project=blahblah-2312312)。
我看到命名的权限storage.objects.create
,并假设我需要将其添加到服务帐户。
为了调查服务帐户的当前设置,我运行了以下命令:
$ gcloud iam service-accounts describe blahblah-2312312@appspot.gserviceaccount.com
displayName: App Engine default service account
email: blahblah-2312312@appspot.gserviceaccount.com
etag: BwVwvSpcGy0=
name: projects/blahblah-2312312/serviceAccounts/blahblah-2312312@appspot.gserviceaccount.com
oauth2ClientId: '98989898989898'
projectId: blahblah-2312312
uniqueId: '12312312312312'
$ gcloud iam service-accounts get-iam-policy blahblah-2312312@appspot.gserviceaccount.com
etag: ACAB
我不确定是否有办法从中获取更多详细信息,也不确定 etag ACAB 表示什么。
在查看此文档(https://cloud.google.com/iam/docs/granting-roles-to-service-accounts)后,我认为我需要授予权限。但是,我不完全确定如何从 JSON 示例出发,以及它应该是什么结构,然后关联策略,或者这是否是正确的路径。
{
"bindings": [
{
"role": "roles/iam.serviceAccountUser",
"members": [
"user:alice@gmail.com"
]
},
{
"role": "roles/owner",
"members": [
"user:bob@gmail.com"
]
}
],
"etag": "BwUqLaVeua8=",
}
例如,我的问题是:
- 我需要自己制作etag吗?
- 我在成员数组中使用什么电子邮件地址?
我看到此命令作为示例列出
gcloud iam service-accounts add-iam-policy-binding \
my-sa-123@my-project-123.iam.gserviceaccount.com \
--member='user:jane@gmail.com' --role='roles/editor'
我不明白为什么我必须指定两个准电子邮件地址。一个是服务帐户,一个是与服务帐户关联的用户。这是否意味着用户jane@gmail.com
可以在服务帐户的凭据下进行操作?我可以让服务帐户自己拥有我在云功能中使用的权限吗?
有没有更简单的方法可以只使用命令行而不手动编辑 JSON?
而且,一旦我正确建立了我的凭据,我是否需要使用 JSON 服务帐户文件,如许多示例所示:
var admin = require('firebase-admin');
var serviceAccount = require('path/to/serviceAccountKey.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
});
或者,我是否可以只调用admin.initializeApp()
“......在运行时,Cloud Functions 使用服务帐户 PROJECT_ID@appspot.gserviceaccount.com......”,该函数将自动获得这些权限?