如何在允许更新时保护Firestore文档中的字段?

问题描述 投票:0回答:1

使用Firebase Firestore我将聊天室详细信息存储在包含以下数据的文档中:

roomName
roomAvatar
createDate
isDeleted

我的应用程序和我的规则要求在文档的“创建”上设置这些字段。但是,我还想允许授权用户“更新”文档。

我已经进行了检查,只允许某些用户更新文档并验证他们不能修改像“createDate”这样的字段。但是,我似乎无法通过传递FiledValue.delete()或使用ref.set(objectMissingCreateDate)来创建强制授权用户不删除“createDate”字段的规则。

最后,如果客户端只尝试更新一个或两个字段,我认为不应要求客户端传递更新的所有数据字段。

我有一个“更新”规则如下:

allow update: if isAuthenticated() && isMemberOfRoom() && 
  (
    (!("roomName" in request.resource.data) || 
      request.resource.data.roomName == resource.data.roomName || 
      hasRoomPermission("UpdateRoom")) &&
    (!("roomAvatar" in request.resource.data) || 
      request.resource.data.roomAvatar == resource.data.roomAvatar || 
      hasRoomPermission("UpdateRoom")) &&
    (!("createDate" in request.resource.data) || 
      request.resource.data.createDate == resource.data.createDate) &&
    (!("isDeleted" in request.resource.data) || 
      request.resource.data.isDeleted == resource.data.isDeleted || 
      hasRoomPermission("DeleteRoom"))
  );

主要问题是保护来自传递FieldValue.delete()或使用[Android] docRef.set()的授权用户的数据,同时缺少必需的值。

我甚至会接受关闭非管理员客户端的FieldValue.delete()和破坏性“设置”操作的功能。

firebase google-cloud-firestore firebase-security-rules
1个回答
0
投票

在Doug和Puff的评论的帮助下,我意识到我做错了什么。

首先,我不知道只通过几个字段的更新(或带有合并选项的集合)将导致其余字段从数据库的request.resource复制到resource上。

其次,一组(没有合并)或传入FieldValue.delete()将是request.resource错过现有文档字段的唯一方式。

有了这些新知识,我将以前的规则更新为以下内容:

allow update: if isAuthenticated() && isMemberOfRoom() && 
  (
    ("roomName" in request.resource.data && 
      (request.resource.data.roomName == resource.data.roomName || 
      hasRoomPermission("UpdateRoom"))) &&
    ("roomAvatar" in request.resource.data && 
      (request.resource.data.roomAvatar == resource.data.roomAvatar || 
      hasRoomPermission("UpdateRoom"))) &&
    ("createDate" in request.resource.data && 
      request.resource.data.createDate == resource.data.createDate) &&
    ("isDeleted" in request.resource.data && 
      (request.resource.data.isDeleted == resource.data.isDeleted || 
      hasRoomPermission("DeleteRoom")))
  );

这些新规则现在使createDate锁定客户端,同时允许为通过权限测试的客户编辑roomNameroomAvatarisDeleted。它也不允许使用FieldValue.delete()更新任何这些字段或调用docRef.set(object),其中对象缺少其中一个字段。

© www.soinside.com 2019 - 2024. All rights reserved.