我在Firestore的Firebase控制台中测试了此安全规则结构,我认为它可以满足我的要求,即在 organization 级别为用户保留角色图并强制执行组织的权限通过始终使用get()
方法引用上级组织来子集合。
service cloud.firestore {
match /databases/{database}/documents {
// ORGANIZATIONS collection
match /organizations/{organization} {
function isSignedIn() {
return request.auth != null;
}
function getRole(rsc) {
// Read from the 'roles' map in the resource (rsc)
return rsc.data.roles[request.auth.uid];
}
function isOneOfRoles(rsc, array) {
// Determine if the user is one of an array of roles
return isSignedIn() && (getRole(rsc) in array);
}
allow write: if isSignedIn();
allow read: if isSignedIn() && isOneOfRoles(resource, ['owner']);
// PROJECTS subcollection
match /projects/{project} {
allow write: if isSignedIn() && isOneOfRoles( get(/databases/$(database)/documents/organizations/$(organization)), ['owner']);
allow read: if isSignedIn() && isOneOfRoles(get(/databases/$(database)/documents/organizations/$(organization)), ['owner', 'member']);
}
}
}
}
现在,由于查询必须符合安全规则,因此我试图了解如何使用将与上述安全规则相匹配的Javascript客户端进行查询。
我有一个有效的查询来获取如下所示的组织:
db.collection('organizations').where(`roles.${currentUser.uuid}`, '==', 'owner').get()
基于以下文档结构:
organizations (collection)
{organization} (document)
name: string,
roles: {
<user_id_1>: "owner",
<user_id_2>: "member"
},
projects (subcollection)
是否有可能在Javascript client中有一个查询(或什至多个查询)来检查用户在organization
级别上是否具有特定角色并检查projects
中的文档属性子集合,类似于安全规则?
编辑:最终,我认为这是authorization
的问题,以及Firestore是否支持我的方法。目前看来,最好的选择是递归通配符语法-match /organization/{document=**}
-但由于匹配 any 条件允许访问所有嵌套文档,因此这种方法似乎不太安全。
理想情况下,我可以在客户端查询中指定一个收集路径,例如organizations/{organization}/projects
,并有一种方法可以指定在授予对{{的访问权限之前,必须检查{organization}
角色1}}子集合。
潜在的解决方案:以下安全规则结构还有很多不足之处,但这似乎是一种改进。我只使用递归通配符语法,而不是匹配特定子集合的路径。有谁知道更好的解决方案?
projects