Возможность только для текущего подключенного (не аутентифицированного) пользователя и администратора читать и писать в определенном месте

Есть ли способ написать правило безопасности или есть ли какой-либо другой подход, который позволил бы только подключенному в данный момент (не прошедшему проверку подлинности) пользователю записывать/читать в определенное место - администратор также должен иметь возможность писать/читать? Можно ли написать правило, которое запрещает пользователям читать полный список записей и разрешает им только чтение записи, которая соответствует некоторому идентификатору, переданному от клиента?

Я пытаюсь обмениваться некоторыми данными между пользователем и приложением Node.js через Firebase, и эти данные не должны быть доступны для чтения или записи кем-либо, кроме пользователя и/или администратора.

Я знаю, что одним из решений будет то, что пользователь запрашивает токен аутентификации на моем сервере и использует его для аутентификации в Firebase, и это позволит написать правило, которое предотвращает чтение и запись. Однако я пытаюсь избежать подключения пользователя к моему серверу, поэтому это решение не является первым вариантом.

Это сценарий, основанный на сеансе, который недоступен в Firebase, но у меня есть некоторые идеи, которые могли бы решить эту проблему, если бы они были реализованы до управления сеансом:

  • возможно, разрешить администратору записывать в /.info/ расположение, которое клиент наблюдает за каждым изменением и может читать только при активном соединении - если я правильно понял, как работает .info
  • возможно, создание местоположения .temp для этой цели
  • возможно, предоставление администратору и подключенному клиенту большего доступа к информации о соединении, которая будет содержать некоторый уникальный идентификатор соединения, который можно использовать для создания местоположения с этим именем и использования его внутри правила, чтобы предотвратить чтение и перечисление другим пользователям

Спасибо


person user2343398    schedule 02.05.2013    source источник
comment
Переместил вопросы сверху, может так будет понятнее.   -  person user2343398    schedule 02.05.2013


Ответы (1)


Это похоже на классическую проблему XY (т. актуальной проблемы).

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

1) Храните данные по пути, который невозможно угадать

Создайте UUID или GID или, если мы не говорим здесь о безопасности на уровне банка, просто обычный идентификатор Firebase (firebaseRef.push().name()). Затем пусть сервер и клиент взаимодействуют по этому пути.

Это позволяет избежать необходимости в правилах безопасности, поскольку URL-адреса невозможно угадать или они достаточно близки к нему, в случае идентификатора Firebase для обычного использования.

Пример клиента:

var fb = new Firebase(MY_INSTANCE_URL+'/connect');
var uniquePath = fb.push();
var myId = uniquePath.name();

// send a message to the server
uniquePath.push('hello world');

С сервера просто следите за connect, каждый подключающийся — это новый клиент:

var fb = new Firebase(MY_INSTANCE_URL+'/connect');
fb.on('child_added', newClientConnected);

function newClientConnected(snapshot) {
   snapshot.ref().on('child_added', function(ss) {
       // when the client sends me a message, log it and then return "goodbye"
       console.log('new message', ss.val());
       ss.ref().set('goodbye');
   });
};

В ваших правилах безопасности:

{
   "rules": {
       // read/write are false by default

       "connect": {
          // contents cannot be listed, no way to find out ids other than guessing

          "$client": {
             ".read": true,
             ".write": true
          }
       }
   }
}

2) Используйте аутентификацию Firebase

Вместо того, чтобы тратить столько усилий, чтобы избежать аутентификации, просто используйте стороннюю службу, например Встроенная аутентификация Firebase или Singly (которая поддерживает Firebase). Это лучшее из обоих миров, и модель, которую я использую в большинстве случаев.

Ваш клиент может аутентифицироваться напрямую в одной из этих служб, никогда не касаясь вашего сервера, а затем аутентифицироваться в Firebase с помощью токена, что позволяет вступить в силу правилам безопасности.

person Kato    schedule 02.05.2013
comment
Спасибо за ваш ответ. @1) возможно, я ошибся, но в этом случае вам даже не нужно гадать, вы просто делаете в любом другом клиенте var fb = new Firebase(MY_INSTANCE_URL+'/connect'); fb.on('child_added', newClientConnected);, и вы можете видеть все, что написано для подключения. Это также было задано в моем посте. Можно ли написать правило, которое запрещает пользователям читать полный список записей и позволяет им только читать запись, которая соответствует некоторому идентификатору, переданному от клиента? @2) Это требование, согласно которому пользователю не нужно проходить аутентификацию. Иначе я бы уже использовал это - person user2343398; 02.05.2013
comment
ОК, с использованием ответа в правил безопасности Firebase: Разрешить чтение для всего, кроме одного поля и вашего 1. варианта - неугадываемые ссылки - у меня есть решение. Мне пришлось добавить правило: { "rules": { "connect" : { "$connectID" : { ".write": true, ".read": true } } } } Это позволяет читать местоположение только в том случае, если вы знаете/угадываете его, и отключает другие, перечисляющие полный список подключений. Спасибо - person user2343398; 02.05.2013
comment
Да, это билет; Я добавлю примечание о правилах безопасности в свой пост (извините, что это было инстинктивно для меня). Надеюсь, это работает хорошо для вас :) - person Kato; 02.05.2013
comment
Кажется, это противоречит цели оставить бэкэнд-логику Firebase. В этой конкретной проблеме пользователю нужно сделать так много всего, что можно было бы сделать в самой Firebase. - person Adam Grant; 18.10.2013