Firebase: установка правил безопасности в зависимости от ролей пользователей
Я хотел бы реализовать правила безопасности "write" в Firebase в зависимости от ролей пользователей.
Моя структура данных выглядит так:
+ myapp
+ users
+ john
+ email: "john@mail.com"
+ roles
+ administrator: true
+ mary
+ email: "mary@mail.com"
+ roles
+ moderator: true
+ ...
+ documents
+ -JVmo6wZM35ZQr0K9tJu
+ ...
+ -JVr56hVTZxlAI5AgUaS
+ ...
+ ...
Я хочу, например, чтобы только пользователи-администраторы могли писать документы.
Вот правила, к которым я пришел:--7-->
{
"rules": {
".read": true,
"$documents": {
".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true"
}
}
}
но это не работает: даже пользователи администратора не могут писать документы...
Мое понимание правил безопасности Firebase полностью дефект?
обновление:
Непосредственно перед ответом Дженни (верьте или нет :-), я реализовал то же самое решение, которое он предоставляет (конечно, на основе комментария Като).
Хотя, делая некоторые тесты, я не мог позволить правилам структурироваться
{
"rules": {
"documents" {
"$document" {
".read": "root.child('users').child(auth.uid).child('roles').child('documents').child('read').val() === true",
".write": "root.child('users').child(auth.uid).child('roles').child('documents').child('write').val() === true"
}
}
}
}
работа... Я всегда получал такое предупреждение:
"FIREBASE WARNING: on() or once() for /documents failed: Error: permission_denied: Client doesn't have permission to access the desired data. "
поэтому я придумал эту структуру, вместо этого:
{
"rules": {
"documents" {
".read": "root.child('users').child(auth.uid).child('roles').child('documents').child('read').val() === true",
".write": "root.child('users').child(auth.uid).child('roles').child('documents').child('write').val() === true"
}
}
}
, который действительно работает для меня: если я установил роли / клиенты / чтение узла true на пользователя он может читать все документы, иначе он не может (и то же самое для записи).
теперь мои сомнения:
- почему я не мог позволить первому правилу (как предложил Като) работать?
- вы видите какую-либо возможную дыру в безопасности в правиле, как тот, который я придумал?
- правила, использующие переменные"$", необходимы / полезны, даже если вам не нужно разрешать / запрещать читаемость / записываемость каждого документ основываясь на этом ключе, но вы просто хотите разрешить/запретить читабельность/writeability узла в целом?
1 ответов
основываясь на именах ваших пользовательских записей, они не совпадают auth.uid
, а это Простой Вход id, например twitter:2544215
.
начните с настройки ваших пользователей, которые будут сохранены их простым uid входа:
+ myapp
+ users
+ twitter:2544215
+ email: "john@mail.com"
+ roles
+ administrator: true
+ twitter:2544216
+ email: "mary@mail.com"
+ roles
+ moderator: true
+ ...
+ documents
+ -JVmo6wZM35ZQr0K9tJu
+ ...
+ -JVr56hVTZxlAI5AgUaS
+ ...
+ ...
затем добавьте правило безопасности, чтобы администраторы могли получить доступ documents
. У вас есть несколько вариантов здесь, в зависимости от вашего конкретного случая использования.
-
дать администраторам написать доступ к содержимому каждого документ:
{ "rules": { "documents": { "$documents": { ".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true" } } } }
-
или, альтернативно, дайте им доступ ко всей коллекции:
{ "rules": { "documents": { ".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true" } } }
разница между этими двумя, являясь $documents
переменная, которая перемещает правило безопасности на один шаг дальше в иерархию.
(это была в основном просто агрегация комментариев @Kato в форму ответа)