Правило безопасности Firestore для ограничения записи в поля для установки и обновления? - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь написать некоторые правила безопасности Firestore, которые позволяют пользователям писать только в определенные поля в своих документах (например, электронная почта, пол, предпочитаемое имя, адрес).

Я написал следующее правило записи, чтобы ограничить доступ к указанным c полям:

  match /databases/{database}/documents {
    match /users/{userId} {
        allow read: if userIsAuthenticated() 
                     && userIsAccessingTheirData(userId);

      // Users can always write to specific fields                
      allow write: if userIsAuthenticated() 
                     && userIsAccessingTheirData(userId)
                     && request.resource.data.keys().hasOnly(["preferredName","gender", "email", "address"]);

Правила хорошо работают, когда мы вызываем userDo c .set в коде, но не работают, когда мы вызываем userDo c .update .

Используя эмулятор правил Firestore, я вижу, что когда мы вызываем "set", request.resource.data.keys() имеет только те поля, которые передаются в вызове, но когда я вызываю "update", все поля документ находится в коллекции ключей :-(, что делает невозможным фильтрацию.

Есть ли способ написать правило безопасности, ограничивающее поля, как указано выше, которое работает как для установки, так и для обновления?

1 Ответ

1 голос
/ 26 марта 2020

Переменная request.resource представляет документ в том виде, в каком он будет существовать после успешного завершения операции (, если это, конечно, успешно). Так что request.resource содержит не , содержит только обновляемые поля, но также и другие значения из существующего документа.

Всегда можно было проверить, обновляется ли поле с помощью сравнение request.resource.data.fieldname с resource.data.fieldname.

Но недавно в правила безопасности была введена новая функция affectedKeys(), которая отображает только дельту:

// This rule only allows updates where "a" is the only field affected
allow update: if request.resource.data.diff(resource.data).affectedKeys().hasOnly(["a"]);

См. также выпуск примечания к правилам безопасности Firebase .

...