Подтвердить что ты не робот

Правило безопасности Firebase дает разрешение на отказ?

Я пытаюсь установить правильные правила безопасности для своего приложения.

Обзор приложения, которое я пишу, заключается в том, что пользователи могут регистрироваться с помощью электронной почты и пароля (я использую Firebase Simple Login для этого, который отлично работает). После входа в систему пользователь может добавить свои todos.

angularFire('https://<firebase>/firebaseio.com/todos', $scope, 'todos');

И чтобы добавить новое todo к любому пользователю, я просто обновляю модель todos.

$scope.todos.push({
   user: '[email protected]',
   todo: 'What to do?'
});

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

  {
    "rules": {
      ".read": true,
      "todos": {
        ".write": "auth != null",
        ".validate": "auth.email == newData.child('user').val()"
      }
    }
  }

Но он не позволяет даже аутентифицированному пользователю писать любые данные и выдавать ошибку, "ПРЕДУПРЕЖДЕНИЕ FIREBASE: on() или один раз() для /todos не удалось: Ошибка: permission_denied."

Но если я добавлю следующие данные в симулятор, то он работает как ожидалось.

{user: "[email protected]", todo: 'What to do?'} 

Вот журнал:

/todos:.write: "auth != null"
    => true
/todos:.validate: "auth.email == newData.child('user').val()"
    => true
/todos:.validate: "auth.email == newData.child('user').val()"
    => true

Write was allowed.
4b9b3361

Ответ 1

push добавляет новый дочерний элемент со случайно сгенерированным идентификатором (в хронологическом порядке) до /todos. Таким образом, newData не указывает на то, что, по вашему мнению, указывает. Измените свои правила на:

{
  "rules": {
    ".read": true,
    "todos": {
      "$todoid": {
        ".write": "auth != null",
        ".validate": "auth.email == newData.child('user').val()"
      }
    }
  }
}

Обновление: Правило выше допустимо, но angularFire в настоящее время записывает весь массив на сервер, что приводит к сбою auth. Вместо этого вы можете использовать angularFireCollection, чтобы написать только новый TODO, например:

$scope.todos = angularFireCollection(new Firebase(URL));

$scope.todos.add({user: '[email protected]', todo: 'What to do?'});

Существует открытая проблема для оптимизации поведения angularFire, когда новые элементы добавляются в список, но тем временем вы можете использовать angularFireCollection, чтобы получить правильное поведение.