Правила безопасности Firebase — Разрешить чтение только пользовательскому контенту

У меня есть данные Firebase, структурированные примерно так:

+ tasks
  + task_id
    + title
    + user
    + ...
+ users
  + ...

Из внешнего интерфейса (с использованием AngularJS и AngularFire (плюс встроенный SimpleLogin)) — когда вошедший в систему пользователь создает задачу, пользовательский идентификатор пользователя (например, simplelogin: 2) помещается в пользовательскую часть создаваемой задачи.

Когда пользователь вошел в систему, он может просматривать только свои задачи, используя:

$firebase( ref.orderByChild('user').equalTo(User.uid) );

Следующим шагом является защита данных, с чем я борюсь. Я пробовал:

"tasks": {
   ".indexOn": ["user", "order"],
   ".write": "auth != null",
   ".read": "auth != null && data.child('user').val() == auth.uid",
     "$task": {
        "title": {
           ".validate": "newData.isString() && newData.val().length <= 1000"
        },
        "completed": {
        },
        "time_added": {
            ".validate": "newData.val() <= now"
        },
        "order": {
        },
        "user": {
            ".validate": "newData.val() != null && newData.val() == auth.uid"
        },
        "$other": {
           ".validate": false
        }
     }
  }

а также:

"tasks": {
     "$task": {
       ".indexOn": ["user", "order"],
       ".write": "auth != null",
       ".read": "auth != null && data.child('user').val() == auth.uid",

        "title": {
           ".validate": "newData.isString() && newData.val().length <= 1000"
        },
        "completed": {
        },
        "time_added": {
            ".validate": "newData.val() <= now"
        },
        "order": {
        },
        "user": {
            ".validate": "newData.val() != null && newData.val() == auth.uid"
        },
        "$other": {
           ".validate": false
        }
     }
  }

Однако я получаю:

Ошибка: permission_denied: у клиента нет разрешения на доступ к нужным данным.

Где я ошибаюсь?


person mcnamee    schedule 26.01.2015    source источник
comment
Вы не можете использовать правила безопасности в качестве фильтра. Это включает использование с запросами. Поскольку запрос, по сути, должен читать tasks/, чтобы получить совпадающие дочерние элементы, он терпит неудачу, поскольку доступ для чтения не разрешен на родительском (т.е. итеративном) уровне.   -  person Kato    schedule 27.01.2015
comment
Привет @Kato - что вы порекомендуете в этой ситуации, когда все задачи должны быть доступны только для пользователей (1 или более) в поле «пользователь». Или я неправильно структурирую данные?   -  person mcnamee    schedule 28.01.2015
comment
Ознакомьтесь с руководством по структурированию данных. Существует раздел под названием «Создание масштабируемых данных, которые охватывают индексы». Какой-то вариант этого был бы необходим здесь.   -  person Kato    schedule 28.01.2015
comment
@mcnamme Сейчас я столкнулся с той же проблемой. Вы уже нашли свое решение?   -  person Steffen    schedule 13.03.2015


Ответы (1)


Коллекция tasks не имеет дочернего элемента user. У каждой конкретной задачи есть user дочерних элемента. Итак, вам нужно переместить правило чтения на один уровень ниже:

"tasks": {
    "$task_id" {
        ".read": "auth != null && data.child('user').val() == auth.uid",
    }

Также см. примеры на: https://www.firebase.com/docs/security/guide/user-security.html

person Frank van Puffelen    schedule 26.01.2015
comment
Спасибо за ваше время @Frank - к сожалению, это все еще не работает - я добавил больше информации из правил безопасности на случай, если это поможет. - person mcnamee; 27.01.2015
comment
Этот ответ пытается отфильтровать правильно? И я думал, что фильтрация невозможна. - person Christiaan Westerbeek; 24.04.2015
comment
Хороший вопрос @ChristiaanWesterbeek! Не уверен, пропустил ли я это раньше или это было в редактировании. Можете ли вы добавить ответ на это? Я проголосую. :-) - person Frank van Puffelen; 11.02.2016