Как использовать правила Firebase, чтобы давать разрешение только определенным листовым узлам

Мой основной вопрос: как настроить правила Firebase, чтобы разрешить доступ только к определенным листовым узлам от их родителя?

Допустим, у меня есть данные, которые выглядят так:

root: {
  posts: {
    post1: {
      user: "foo",
      post: "this is a post",
      restricted: false
    },
    post2: {
      user: "bar",
      post: "this is another post",
      restricted: true
    },
    post3: {
      user: "bar",
      post: "this is my final post",
      restricted: false
    }
  }
}

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

Примечание. Я использую $bind angularFire для синхронизации узлов.

Я не верю, что это возможно, но я хотел бы иметь возможность настроить свои правила примерно так:

{
  "rules": {
    "posts": {
      ".read": "auth.admin || $post.hasChild('restricted').val() !== true",
      "$post": {
      }
    }
  }
}

Как это делают другие пользователи? Спасибо.


person yodaisgreen    schedule 10.01.2014    source источник


Ответы (2)


Для этого можно использовать выражение data.hasChild:

{
  "rules": {
    "posts": {
      ".read": "auth.admin || data.hasChild('restricted').val() !== true"
    }
  }
}

Однако это не рекомендуемый подход, и он не будет работать на практике. Правила безопасности не подходят для фильтрации данных на основе доступа - вы увидите ошибки отказа в разрешении в консоли, потому что angularFire попытается прочитать все сообщения из /blog, и это не удастся.

Вместо этого каждый пользователь должен знать, к каким сообщениям у него есть доступ, и получать только их напрямую. Вы можете использовать push() (или $add в angularFire) для генерации случайных идентификаторов сообщений и установки правил безопасности, чтобы вы могли получить доступ к данным, например, если вы знаете идентификатор сообщения.

person Anant    schedule 10.01.2014
comment
Если я привяжусь к сообщениям, используя первый описанный вами метод, я получу только дочерние элементы, к которым у пользователя есть доступ, и получу несколько сообщений об отказе в доступе для дочерних элементов, к которым у меня нет доступа? Что в этом плохого, кроме грязной консоли? Это кажется самым чистым способом сделать это. Основываясь на вашем альтернативном предложении, я думаю, что мне придется поддерживать альтернативную структуру, отражающую мои данные, которая обеспечивает полный доступ для чтения и хранит все разрешения для всех моих данных. Кажется, что это добавляет сложности к тому, что должно быть довольно простым и очень распространенным вариантом использования. Я что-то упускаю? - person yodaisgreen; 12.01.2014
comment
На самом деле вы вообще не получите никаких дочерних элементов, даже если некоторые из них доступны для чтения — опять же — правила безопасности не предназначены для фильтрации элементов. - person Anant; 13.01.2014

Я считаю, что канонический способ сделать это — поместить правило непосредственно в элемент для чтения, а не в коллекцию.

{
  "rules": {
    "posts": {
      "$post": {
        ".read": "auth.admin || data.hasChild('restricted').val() !== true"
      }
    }
  }
}

person Titou    schedule 11.06.2018