Пользовательские правила безопасности для 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;
}