Проверьте пользовательские поля Firestore

# #google-cloud-firestore #firebase-security

Вопрос:

У нас есть коллекция токенов /funTokens , в которой каждый идентификатор документа является идентификатором токена, а данные документа содержат name поле (идентификатор токена также является полем).

Мы хотели бы запросить коллекцию из Интернета (javascript) и разрешить доступ к документу только в том случае, если запрос содержит name поля и и соответствует token им.

примечание — существует много токенов, и токен не является пользователем

Пример — кто-то должен иметь возможность открыть funExample.com/getTokenData?token=123amp;name=bob URL-адрес, и в запросе javascript Firestore мы передадим эти параметры и проверим их в правилах безопасности. Таким образом, запрос разрешит доступ только к этому документу:

 /funTokens/123: {  token: 123,  name: bob,  stuf: lt;gt; }  

Возможно ли это?

Комментарии:

1. Вы спрашиваете о правиле безопасности для этой потребности или задаете правильный запрос?

2. Спасибо! Я использую следующий запрос: db.doc( funTokens/${токен} ).get().then(...) , но я не уверен, как вставить имя в запрос и каким должно быть правило безопасности

3. Давайте начнем с запроса, предполагая, что token_id является переменной, содержащей идентификатор токена, пожалуйста, попробуйте выполнить следующее db.collection('funTokens').doc(token_id).get().subscribe(token =gt; token=token) и сообщите мне, если это удастся. На данный момент, пожалуйста, используйте правила общественной безопасности, чтобы каждый запрос был разрешен любому

4. Да, это работает

5. В firebase вы запрашиваете конкретный документ, поэтому я думаю, что вы не можете вставить в get вызов token_id , а также name . Правило, которое вам нужно использовать для подтверждения того, что запрос содержит идентификатор token_id, таково: match /funTokens/{token_id}{ allow read: if request.path[4] == token_id; } если вы хотите изменить базу данных, есть другие варианты, чтобы получить то, что вы хотите

Ответ №1:

Запрос, предполагающий token_id , что переменная, содержащая идентификатор токена, является:

 db.collection('funTokens').doc(token_id).get().subscribe(token =gt; token=token)  

В firebase вы запрашиваете конкретный документ, поэтому я думаю, что вы не можете вставить в get вызов token_id , а также name .

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

 match /funTokens/{token_id} {  allow get: if request.path[4] == token_id;  }   

Но, как упоминал @l1b3rty в комментарии, это правило по определению всегда будет верным. Таким образом, вам на самом деле не нужно принимать какое-либо правило allow read: true , так как, если запрос содержит token_id то, что ему разрешено читать.

Если я правильно понимаю, ваша безопасность построена на том факте, что только тот, кому разрешено читать токен, должен знать об token_id этом . Таким token_id образом, это своего рода секрет, поэтому вам нужно заблокировать list операцию, поскольку allow list она позволяет пользователю прочитать всю коллекцию или запросить коллекцию, чтобы пользователь получил все идентификаторы token_id. Поэтому вам следует использовать следующее правило:

 match /funTokens/{token_id} {  allow get: true;  allow list: false; }   

Если вы хотите изменить структуру БД, есть и другие варианты, чтобы получить то, что вы хотите

Комментарии:

1. @алон. Пожалуйста, дайте нам знать, поможет ли вам приведенный выше ответ.

2. Ваше правило по определению всегда будет истинным это не проверка имени

3. @l1b3rty ты прав. Я просто отредактирую свой ответ, пожалуйста, взгляните

4. Спасибо! это не полностью решает мою проблему, так как не устраняет необходимость проверки имени, но это снизит риск

Ответ №2:

Вам нужно будет найти способ указать имя И токен в запросе. Поэтому я бы сделал следующее:

  1. Измените структуру документа таким образом, чтобы имя документа также содержало name поле
     /funTokens/123_bob: {  token: 123,  name: bob,  stuf: lt;gt; }  
  2. Тогда правило простое:
     match /funTokens/{doc_id} {  allow get: if true;  }   

Если вы не можете изменить имя документа, вам придется использовать облачную функцию, которая

  1. возьмите на входе token id и name
  2. запросите Firestore для документа, используя token id
  3. убедитесь, что имена совпадают
  4. верните документ cotent или ошибку в зависимости от предыдущего шага