Только для чтения дочерние элементы списка, у которых есть поле со значением auth.uid - PullRequest
0 голосов
/ 08 июня 2018

Это моя структура БД

"tasks"
  "$taskId"
      ...
      "user": "firebase user id"

Я уже написал правило ".read": data.child('user').val() === auth.uid" под $taskId.Когда я пытаюсь получить доступ к одной задаче, это правило вступает в силу.

Будет ли это также гарантировать, что если я напишу запрос наподобие firebase.database().ref('/tasks').orderByChild('status').limitToFirst(1), я получу только те задачи, у которых поле идентификатора пользователя равно auth.uid.Или я должен также написать .read предложение под tasks

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

В вашем вопросе есть несколько аспектов, на которые необходимо ответить:

1 / На каком уровне следует писать правила безопасности?

Если вы пишете только на* Уровень 1007 *, как показано ниже, вы не сможете запросить весь набор задач.

Вы можете проверить его, выполнив следующие действия:

Правила:

{
  "rules": {
    "tasks": {
       "$taskID": {
        ".read": "auth != null",
        ".write": "auth != null"
      }
    }
  }
}

JS:

  var db = firebase.database();
  var ref = db.ref('tasks');

  firebase.auth().signInWithEmailAndPassword("....", "....")
    .then(function(userCredential) {
      ref.once('value').then(function(snapshot) {
        snapshot.forEach(function(childSnapshot) {
           console.log(childSnapshot.val());
        });
     });
  });

Это не будет выполнено с сообщением «Ошибка: access_denied at / tasks: у клиента нет прав доступа к нужным данным.»

При изменении var ref = db.ref('tasks'); var ref = db.ref('tasks/123456'); (123456 - существующий идентификатор задачи), вы получите результат.

Если вы измените свои правила на следующие, два предыдущих запроса будут работать.

{
  "rules": {
    "tasks": {
        ".read": "auth != null",
        ".write": "auth != null"
    }
  }
}

2 / Как сделать, чтобы получить только те задачи, в которых поле идентификатора пользователя имеет вид auth.uid?

Первое, на что следует обратить внимание, это то, что «Правила не являются фильтрами», как подробно описано здесь.: https://firebase.google.com/docs/database/security/securing-data#rules_are_not_filters

Так что если вы реализуете правила безопасности следующим образом:

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

Вам нужно будет написать квУбедитесь, что включает такое же ограничение для пользовательского идентификатора пользователя, как показано ниже:

var db = firebase.database();

firebase.auth().signInWithEmailAndPassword("....", "....")
  .then(function(userCredential) {

      var ref = db.ref('tasks').orderByChild('user').equalTo(userCredential.user.uid);

      ref.once('value').then(function(snapshot) {
         snapshot.forEach(function(childSnapshot) {
            console.log(childSnapshot.val());
         });
     });

});

Но этот запрос не будет работать , опять-таки, потому что "Ошибка: license_deniedat / tasks: Клиент не имеет разрешения на доступ к нужным данным. "

Вы также не можете выполнить следующее, так как" Более мелкие правила безопасности переопределяют правила на более глубоких путях. ":

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

Одним из решений является использование правил на основе запросов (см. Документ здесь ) и запись ваших правил следующим образом:

{
  "rules": {
    "tasks": {
        ".read": "auth != null &&
            query.orderByChild == 'user' &&
            query.equalTo == auth.uid",
        ".write": "auth != null"
    }
  }
}

Однако, как вы, вероятно, заметили,это не позволит вам упорядочить ваш запрос (и отфильтровать его) по чему-то другому, чем user (например, status), поскольку «Вы можете использовать только один метод order-by за раз».

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

"tasks"
  "$taskId"
      ...
      "user": "firebase user id"
"tasksByUser"
  "$userId"
      "$taskId"
      ...

. Вы будете использовать метод update () для записи вдве структуры данных одновременно.Смотри документ здесь .

0 голосов
/ 08 июня 2018

Я дал .read: true под tasks, и он рассматривает правила, написанные под отдельными объектами задачи, прежде чем возвращать результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...