Не могу прочитать все данные с помощью правил безопасности

# #reactjs #firebase-realtime-database #firebase-security

Вопрос:

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

   "Event":{
      "$uid": {
            ".read": "auth.uid == $uid || root.child('Users').child(auth.uid).child('admin').val() == 'admin'",
            ".write": true
        }
 

где мои запросы выглядят так:

    var starCountRef = firebase.database().ref("Event/"); //trying to read all events as admin
    starCountRef.on("value", (snapshot) => {
      const data = snapshot.val();
 

Комментарии:

1. Можете ли вы подробнее объяснить, в чем проблема? У вас есть сообщения об ошибках eny?

2. Я не вижу никаких ошибок, просто он просто не попадает в эту строку const data = snapshot.val(); когда я удаляю правила, он работает

3. Работает ли это, когда вы устанавливаете .read: true ?

4. это работает, но мне нужно сделать это также для «События» без администратора:{ «.чтение»:верно,». запись»: верно }

5. Если это работает: вы уверены, что пользователь, с которым вы тестируете, имеет admin ожидаемое значение?

Ответ №1:

Проблема, с которой мы здесь сталкиваемся, заключается в том, что правила RTDB работают сверху вниз. Это означает, что если одно правило вверху запрещает доступ, не имеет значения, что говорит то, что внизу. В вашем случае предоставление доступа ко всему списку администратору не было бы проблемой, но тогда это было бы также для каждого владельца события. Потому что это, вероятно, не администраторы. И вы можете получить доступ ко всему списку только тогда, когда вы укажете .read выше uid.

Есть один способ, который я мог бы себе представить, чтобы это сработало. Есть query-based правила. Подробнее о них здесь.

Вы могли бы написать свои правила так:

  "Event":{
      ".read": "query.equalTo == auth.uid || 
           root.child('Users').child(auth.uid).child('admin').val() == 'admin'" 
        }
 

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

 db.ref("Event").orderByKey()
                 .equalTo(auth.currentUser.uid)
                 .on("value", cb) 
 

Комментарии:

1. не могли бы вы объяснить, пожалуйста, почему, когда я пытаюсь по-своему, я не вижу никаких правил, которые были бы отклонены из консоли Интернета? Я тоже пробовал по-твоему, но получил пустой объект

2. Причина в том, что вам нужно .read правило выше $uid , чтобы просмотреть все элементы в списке. Это именно тот бахавиур, которого вы видите. Но тогда, когда вы хотите предоставить доступ одному пользователю, который .read должен находиться под $uid . Ваши правила администратора будут работать, но. Если вы поставите правило администратора выше и правило одиночного вызова в uid поле «Один вызов», то всегда произойдет сбой, потому что указанное выше правило администратора вернет значение false.