【发布时间】:2018-06-18 23:46:38
【问题描述】:
对于我的一生,我无法理解为什么以下内容会导致false 允许写入。假设我的 users 集合一开始是空的,我正在从我的 Angular 前端编写以下形式的文档:
{
displayName: 'FooBar',
email: 'foo.bar@example.com'
}
我目前的安全规则:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
function isAdmin() {
return resource.data.role == 'ADMIN';
}
function isEditingRole() {
return request.resource.data.role != null;
}
function isEditingOwnRole() {
return isOwnDocument() && isEditingRole();
}
function isOwnDocument() {
return request.auth.uid == userId;
}
allow read: if isOwnDocument() || isAdmin();
allow write: if !isEditingOwnRole() && (isOwnDocument() || isAdmin());
}
}
}
一般来说,我不希望任何用户能够编辑自己的角色。普通用户可以编辑自己的文档,管理员可以编辑任何人的文档。
为false 存根isEditingRole() 给出了预期的结果,因此我将其范围缩小到该表达式。
写入总是返回错误,我无法确定原因。任何想法或修复都会有所帮助!
编辑 1
我尝试过的事情:
function isEditingRole() {
return request.resource.data.keys().hasAny(['role']);
}
和
function isEditingRole() {
return 'role' in request.resource.data;
}
和
function isEditingRole() {
return 'role' in request.resource.data.keys();
}
编辑 2
请注意,管理员最终会为用户设置角色,因此角色最终可能存在于文档中。这意味着,根据下面的Firestore docs,该请求将有一个role 键,即使它不在原始请求中。
资源中存在的请求中未提供的字段将添加到
request.resource.data。规则可以通过比较request.resource.data.foo和resource.data.foo来测试字段是否被修改,因为知道resource中的每个字段也会出现在request.resource中,即使它没有在写入请求中提交。
据此,我认为排除了“编辑1”中的三个选项。我确实尝试了request.resource.data.role != resource.data.role 的建议,但这也不起作用……我不知所措,开始怀疑 Firestore 中是否真的存在错误。
【问题讨论】:
标签: firebase firebase-security google-cloud-firestore