Geo*_*rey 5 javascript google-cloud-firestore firebase-security-rules
我在Firebase控制台中为Firestore测试了这个安全规则结构,我认为它符合我的要求,即在组织级别为用户保留角色映射,并通过始终使用该方法引用父组织来强制执行组织子集合的权限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']);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,因为查询必须符合安全规则,我试图了解如何使用符合上述安全规则的Javascript客户端进行查询.
我有一个工作查询,以使组织看起来像这样:
db.collection('organizations').where(`roles.${currentUser.uuid}`, '==', 'owner').get()
Run Code Online (Sandbox Code Playgroud)
它基于如下文档结构:
organizations (collection)
{organization} (document)
name: string,
roles: {
<user_id_1>: "owner",
<user_id_2>: "member"
},
projects (subcollection)
Run Code Online (Sandbox Code Playgroud)
是否可以在Javascript客户端中进行查询(甚至多个查询),检查该用户是否是该organization级别的特定角色并检查projects子集合中的文档属性,类似于安全规则的作用?
编辑:最后,我认为这是一个问题,authorization以及Firestore是否支持我的方法.在这一点上,我最好的选择是递归通配符语法 - match /organization/{document=**}但由于匹配任何条件都允许访问所有嵌套文档,因此这种方法似乎不太安全.
理想情况下,我可以organizations/{organization}/projects在我的客户端查询中指定一个集合路径 - 例如,- 并指定{organization}在授予对projects子集合的访问权限之前必须检查角色.
可能的解决方案:以下安全规则结构有很多不足之处,但似乎是一种改进.我只是使用递归通配符语法而不是匹配特定子集的路径.有谁知道更好的解决方案?
service cloud.firestore {
match /databases/{database}/documents {
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);
}
// ORGANIZATIONS
match /organizations/{organization} {
allow write: if isOneOfRoles(resource, ['owner']);
allow read: if isOneOfRoles(resource, ['owner', 'member']);
}
// Any subcollections under ORGANIZATION
match /organizations/{organization}/{sub=**} {
allow write: if isOneOfRoles(get(/databases/$(database)/documents/organizations/$(organization)), ['owner']);
allow read: if isOneOfRoles(get(/databases/$(database)/documents/organizations/$(organization)), ['owner', 'member']);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
70 次 |
| 最近记录: |