对文档的部分写访问

时间:2019-07-16 13:46:03

标签: firebase google-cloud-firestore firebase-security-rules

是否可以设置安全规则,以便仅根据用户角色来更新某些字段?

考虑用户尝试编辑以下文档进行编辑:

/tasks/task1
  {
   "id":"task1",
   "description":"anyone can edit this",
   "sensitive_info":"only editor can edit this",
   "very_sensitive_info":"only admin can edit this",
  }
}

这是具有角色的用户集合

/用户/用户1 { “角色”:“管理员” }

/ users / user2 { “角色”:“编辑” }

/ users / user3 { “角色”:“任何人” }

 match /tasks/{userId} {
        allow read: if true;
        allow create: if true;
        allow update: if <CONDITION HERE>; // <-WHAT GOES HERE?
}

如何允许“ sensitive_info ”字段只能由user2和user1编辑,而不能由user3编辑?

1 个答案:

答案 0 :(得分:1)

写入规则要么允许访问整个文档,要么拒绝它们。因此乍一看,您似乎无法限制用户可以修改的内容。

但是您 可以通过比较文档 之前和 实际控制用户可以写的内容。例如,我经常在规则中进行如下检查:

allow write: if request.resource.data.creator == resource.data.creator

如果creator字段未修改,则允许进行写操作。

实际上,这是如此普遍,以至于我有一个辅助函数:

function isUnmodified(request, resource, key) {
  return request.resource.data[key] == resource.data[key]
}

allow write: isUnmodified(request, resource, 'creator');

请注意,一旦尝试访问不存在的字段,规则将失败,因此使用isUnmodified通常与以下内容并存:

function isNotExisting(request, resource, key) {
  return !(key in request.resource.data) && (!exists(resource) || !(key in resource.data));
}

allow write: isNotExisting(request, resource, 'creator') || isUnmodified(request, resource, 'creator');

如果在正确的范围内定义了辅助函数,则无需传递requestresource并将整个过程缩短为:

function isUnmodified(key) {
  return request.resource.data[key] == resource.data[key]
}

function isNotExisting(key) {
  return !(key in request.resource.data) && (!exists(resource) || !(key in resource.data));
}

allow write: isNotExisting('creator') || isUnmodified('creator');