Пользовательские правила безопасности для Cloud Firestore

Я хочу создать базу данных Cloud Firestore в реальном времени, содержащую группы, в которые пользователи могут вступать и обмениваться информацией с другими членами своей группы. Я хочу сохранить анонимность пользователей, поэтому я вижу, как она реализуется:

  • Создатель группы генерирует ключ группы в формате XXXX-XXXX-XXXX-XXXX
  • Те, кто хочет присоединиться, должны иметь групповой ключ, который они вводят в приложении, после этого они должны иметь возможность читать, создавать и обновлять данные в этой группе.

Так что в основном структура данных выглядит примерно так:

/groups/ : [
    //groups as documents
    "ABCD-0000-0000-0001" : { /*group data model*/ }
    "ABCD-0000-0000-0002" : { /*group data model*/ }
    "ABCD-0000-0000-0003" : { /*group data model*/ }
]

Вопрос в том, какие правила безопасности я должен написать, чтобы пользователи могли читать, создавать и обновлять данные ТОЛЬКО в той группе, к которой они принадлежат (имеют свой групповой ключ)? В то же время, как запретить пользователям узнавать ключи других групп?

2 ответа

Решение

Структура вашей группы может оставаться неизменной

groups (Collection) : [
    //groups as documents
    "ABCD-0000-0000-0001" : { /*group data model*/ }
    "ABCD-0000-0000-0002" : { /*group data model*/ }
    "ABCD-0000-0000-0003" : { /*group data model*/ } ]

И для поддержки доступа у вас может быть другая отдельная коллекция с именем group_users, как

group_users(Collection)/ <group_id>(Document)/ members(Collection)/ :
       uid_1 (document)
       uid_2 (document)    
       ...

Теперь правило разрешать может быть как

service cloud.firestore {
  match /databases/{database}/documents { 
    match /groups/{group_id} {
        allow read, create, update: if exists(/databases/$(database)/documents/group_users/$(group_id)/members/$(request.auth.uid));
    }
  }
}

Когда член присоединяется к группе, вам нужно добавить пользовательский uid в эту новую коллекцию.

group_users/<group_id>/members

Для администраторов вы можете иметь подобную коллекцию, и uid будет добавлен, когда администратор создаст группу.

group_users/<group_id>/admins

Вместо того, чтобы иметь отдельную коллекцию вне коллекции групп, вы можете иметь коллекцию внутри самой группы в качестве альтернативного решения, тогда вам придется изменить модель данных группы в некоторой степени.

Также, к вашему сведению, каждый вызов существует () в правилах безопасности оплачивается (вероятно, как одна операция чтения).

А вот подробная документация, объясняющая практически все возможные аспекты правил безопасности пожарного депо.

Вы можете сохранить идентификатор группы в профиле пользователя. Затем создайте правило, которое разрешает разрешения CRU, только если этот идентификатор группы существует.

db.collection.('users').doc({userId}.update({
  ABCD-0000-0000-0001: true
})

match /groups/{groupId} {
  allow read, create, update: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.$(groupId) == true;
}
Другие вопросы по тегам