Как защитить поля в документе Firestore при разрешении обновления? - PullRequest
0 голосов
/ 20 апреля 2019

Использование Firebase Firestore Я храню данные чата в документах, содержащих некоторые данные, такие как:

roomName
roomAvatar
createDate
isDeleted

Мое приложение и мои правила требуют, чтобы эти поля были установлены при "создании" документа.Однако я также хотел бы разрешить «обновлять» документ авторизованным пользователям.

У меня уже есть проверки, позволяющие только определенным пользователям обновлять документ и проверять, что они НЕ будутразрешено изменять поля, такие как «createDate».Но я не могу создать правило, которое заставляет авторизованного пользователя не удалять поле «createDate», передавая FiledValue.delete () или используя ref.set (objectMissingCreateDate).

Наконец, яНе думайте, что клиенту необходимо обновить все поля данных при обновлении, если он пытается обновить только одно или два поля.

У меня есть правило «обновления», как указано ниже:

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 () и деструктивных операций «set» для клиентов без прав администратора.

1 Ответ

0 голосов
/ 20 апреля 2019

С помощью комментариев Дуга и Паффа я понимаю, что я делаю неправильно.

Во-первых, я не знал, что обновление (или набор с опциями слияния) пропускает только несколько полей,приведет к копированию оставшихся полей на 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 заблокированным для клиентов., при этом позволяя редактировать roomName, roomAvatar и isDeleted для клиентов, которые проходят тесты разрешений.Это также не позволит обновлять ни одно из этих полей с помощью FieldValue.delete() или вызывать docRef.set(object), если объект пропускает одно из этих полей.

...