2014-09-03 3 views
23

Я хотел бы реализовать правила безопасности «write» в Firebase в зависимости от ролей пользователей.
Моя структура данных, как это:Firebase: установить правила безопасности в зависимости от ролей пользователя

+ myapp 
    + users 
    + john 
     + email: "[email protected]" 
     + roles 
     + administrator: true 
    + mary 
     + email: "[email protected]" 
     + roles 
     + moderator: true 
    + ... 
    + documents 
    + -JVmo6wZM35ZQr0K9tJu 
     + ... 
    + -JVr56hVTZxlAI5AgUaS 
     + ... 
    + ... 

Я хочу - например - что только пользователи администратор может создавать документы.
Эти правила я пришел:

{ 
    "rules": { 
    ".read": true, 
    "$documents": { 
     ".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true" 
    } 
    } 
} 

Но это не работает: даже не пользователи администратор может создавать документы ...
ли мое понимание Firebase правил безопасности полностью испорчено?

UPDATE: Как раз перед ответом Дженни (верить или нет :-), я осуществить точно такое же решение, он обеспечивает (конечно основанный на комментарий Като).
Хотя, делая некоторые тесты, я не мог позволить структуре правил,

{ 
    "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" 
    } 
    } 
} 

Который действительно работает для меня: если я устанавливаю ролей/клиент/чтение узла истинен на пользователе он может читать все документы, в противном случае он не может (и то же самое для ш Обряд).

Мои сомнения сейчас:

  • почему я не мог позволить первое правило (как это было предложено Като) работать?
  • Вы видите любое возможное отверстие безопасности в правиле, подобное тому, которое я сделал?
  • :
  • - это правила с использованием переменных «$», необходимых/полезных, даже если вам не нужно разрешать/запрещать чтение/запись каждого документа на основе его ключа, но вы просто хотите разрешить/запретить чтение/отказ читабельности/способность записывать узел в целом?
+6

на основе имен ваших записей пользователей, я предполагаю, что они не совпадают auth.uid (что, вероятно, простой идентификатор входа, например 'twitter: 2544215'). Кроме того, правило '.write', вероятно, должно быть под документами/$ document вместо $ documents (от root), иначе вы разрешаете доступ к любому пути в корне. – Kato

+0

Спасибо, Като! ... Я обязательно изменю ключ моих пользователей (от имени пользователя до uid). Это обычная практика (индексирование пользователей по uid)? Что делать, если я хотел бы разрешить нескольким провайдерам аутентификации для одного и того же пользователя (скажем, «твиттер» и «пароль»)? Я должен привести к тому же пользователю под несколькими ключами ... :-(Но, прежде всего, должен ли я добавлять пользователя в свою коллекцию пользователей, если она подписывается с «социальным» провайдером, или я должен просто подписать ее? – MarcoS

+0

Все эти вопросы являются собственностью вашего прецедента. Вероятно, вы хотите сохранить некоторые данные о своих пользователях, независимо от того, как они вступают в систему. Я не могу думать о каких-либо сайтах, которые позволяют вам входить в одну учетную запись от нескольких поставщиков (т.е. отдельные идентификаторы), кроме агрегированных сервисов, которые объединяют содержимое корма из различных служб. Если вы хотите использовать этот маршрут, создайте свои собственные токены и идентификаторы. – Kato

ответ

24

на основе имен ваших записей пользователей, они не совпадают auth.uid, что, вероятно, Simple Login идентификатор, например twitter:2544215.

Start, корректируя пользователям хранить их Simple Login UID:

+ myapp 
    + users 
    + twitter:2544215 
     + email: "[email protected]" 
     + roles 
     + administrator: true 
    + twitter:2544216 
     + email: "[email protected]" 
     + roles 
     + moderator: true 
    + ... 
    + documents 
    + -JVmo6wZM35ZQr0K9tJu 
     + ... 
    + -JVr56hVTZxlAI5AgUaS 
     + ... 
    + ... 

Далее добавьте правила безопасности, так что администраторы могут получить доступ к documents. У вас есть пара вариантов здесь, в зависимости от вашего конкретного варианта использования.

  1. Чтобы дать администраторам доступ на запись к содержанию каждого документа:

    { 
        "rules": { 
        "documents": { 
         "$documents": { 
         ".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true" 
         } 
        } 
        } 
    } 
    
  2. Или, наоборот, дать им доступ ко всей коллекции:

    { 
        "rules": { 
        "documents": { 
         ".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true" 
        } 
        } 
    } 
    

Разница между этими двумя является переменная $documents, которая перемещает правило безопасности на один шаг дальше в иерархию.

(Это было в основном только агрегация комментариев @Kato в форму ответа)

+0

Спасибо, Дженни! Пожалуйста, ознакомьтесь с обновлением моего вопроса после вашего ответа ... – MarcoS

Смежные вопросы