Правила Firestore вообще не работают с функциями

service cloud.firestore {
  match /databases/{database}/documents {
    match /pool/{poolId} {
      allow read: if request.auth != null;
      allow write: if request.auth != null && get(/databases/$(database)/documents/user/$(request.auth.uid)).data.admin == true;
    }
  }
}

Я написал предыдущие правила, следуя https://firebase.google.com/docs/firestore/security/rules-conditions#access_other_documents. Я ожидал, что для того, чтобы пользователь добавил новый документ в коллекцию pool, документ с идентификатором request.auth.uid должен существовать в коллекции user и иметь запись admin: true .

Но каждый запрос от Functions

    pool.post('/add', async (req, res) => {
        const added = await db.collection('pool').add({
            ...
        }); 
    });

Разрешено добавлять новый документ в коллекцию pool.

Даже следующие правила

service cloud.firestore {
  match /databases/{database}/documents {
    match /pool/{poolId} {
      allow read, write: if false;
    }
  }
}

Не запрещать любые запросы от функций...

В чем проблема правил? Или в функциях есть что-то, из-за чего правила не работают? Или в моей конфигурации проекта...?

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

Mises 13.02.2023 17:29

Что именно вы подразумеваете под «запросом от функций»? Где выполняется запрос? В облачной функции? Я предполагаю, что с помощью pool.post вы передаете приложение Express в свою облачную функцию HTTP.

Renaud Tarnec 13.02.2023 17:41

@Mises, последняя показанная им конфигурация должна предотвращать запись, но функции все еще могут писать, так что есть проблема. Да, он мог проверить context.auth.admin === true в верхней части своей функции и отклонить запрос, но вопрос заключался в том, почему Firestore rules способ защиты Firestore от неавторизованных вызовов функций не работает. Я думаю, что ваша точка зрения верна, и что-то, что можно сделать в дополнение к тому, что он просит в качестве дополнительной меры безопасности. --- firebase.google.com/docs/firestore/security/…

Wesley LeMahieu 13.02.2023 17:42

@Mises Тогда правила работают для чего ...? Разве правила для запросов, поступающих в базу данных Firestore откуда угодно...?

ghchoi 13.02.2023 17:42

@RenaudTarnec Я использую функции Firebase для добавления документа в базу данных Firestore.

ghchoi 13.02.2023 17:43

Правила @ghchoi работают для звонков прямо в базу данных. Например, с помощью библиотеки Firebase JavaScript SDK. Браузер пользователя может обращаться к базе данных, если это разрешено правилами.

Mises 13.02.2023 17:59

@Mises Что мне делать, если я хочу разрешить запросы только от определенных пользователей? Должен ли я использовать такое условие, как if (db.collection('user').get(request.auth.uid))...?

ghchoi 13.02.2023 18:03

@ghchoi Для этого есть много возможностей. Один из способов похож на ваш вопрос. Но вы должны ограничить доступ к «пользовательской» коллекции, чтобы только «суперадмин» мог изменять там документы (Ну, не только, но это просто пример). Второй — проверить токен пользователя: request.auth.token.admin == true но вам нужно будет написать функцию firebase, чтобы назначить это поле токену пользователя.

Mises 13.02.2023 18:09

Ваш вопрос очень распространен. Пожалуйста, прочитайте дубликаты, чтобы понять поведение. Суть в том, что вы не можете контролировать запросы, поступающие от бэкэндов, только от интерфейсов при использовании веб- и мобильных SDK.

Doug Stevenson 13.02.2023 20:21
Конечные и Readonly классы в PHP
Конечные и Readonly классы в PHP
В прошлом, когда вы не хотели, чтобы другие классы расширяли определенный класс, вы могли пометить его как final.
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
Если вы уже умеете работать с React, создание мобильных приложений для iOS и Android - это новое приключение, в котором вы сможете применить свои...
БЭМ: Конвенция об именовании CSS
БЭМ: Конвенция об именовании CSS
Я часто вижу беспорядочный код CSS, особенно если проект большой. Кроме того, я совершал эту ошибку в профессиональных или личных проектах и...
Революционная веб-разработка ServiceNow
Революционная веб-разработка ServiceNow
В быстро развивающемся мире веб-разработки ServiceNow для достижения успеха крайне важно оставаться на вершине последних тенденций и технологий. По...
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Заголовок веб-страницы играет наиболее важную роль в SEO, он помогает поисковой системе понять, о чем ваш сайт.
Конфигурация Jest в angular
Конфигурация Jest в angular
В этой статье я рассказываю обо всех необходимых шагах, которые нужно выполнить при настройке jest в angular.
0
9
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Облачные функции для Firebase используют Node.js Admin SDK, который полностью обходит правила безопасности, поскольку считается «привилегированной средой».

Вы найдете примечание по этому аспекту в документе Firestore :

Примечание. Клиентские библиотеки сервера обходят все функции Cloud Firestore Security. Правила

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

Что мне делать, если я хочу разрешить только запросы от определенных пользователей? Должен ли я использовать такое условие, как if (db.collection('user').get(request.auth.uid))...?

ghchoi 13.02.2023 17:51

Я действительно не понимаю, где тогда использовать правила... Нельзя ли сделать так, чтобы мои Функции не обходили правила безопасности?

ghchoi 13.02.2023 17:54

См. обновление для ограничения вашей облачной функции HTTPS только пользователями Firebase вашего приложения. Для «Я действительно не понимаю, где тогда использовать правила» => Правила применяются, когда клиентские SDK вызывают бессерверную серверную часть Firestore. Серверные SDK обходят их.

Renaud Tarnec 13.02.2023 18:06

Не могли бы вы помочь мне еще немного? Я следовал авторизованной конечной точке HTTPS. Что я дополнительно хочу сделать, так это разрешить только некоторым авторизованным пользователям записывать в «пул» коллекции, в то время как все авторизованные пользователи могут читать коллекцию.

ghchoi 13.02.2023 18:11

Так что я могу заменить const { initializeApp, applicationDefault } = require('firebase-admin/app'); на Client SDKs?

ghchoi 13.02.2023 18:12

Нет, не используйте Clients SDK и продолжайте использовать Admin SDK. Как показано в строках с 61 по 63 в образце, токен Firebase ID, который был передан как токен носителя в заголовке авторизации, декодируется, и вы можете получить пользовательский идентификатор (req.user.uid). Вы должны написать логику в своей облачной функции, которая разрешает (или не разрешает) пользователю, идентифицированному его uid, выполнять определенное действие (чтение или запись).

Renaud Tarnec 13.02.2023 18:52

Обратите внимание, что следующее предложение в моем последнем комментарии «разрешает (или не разрешает) пользователю, идентифицированному его uid, выполнять определенное действие» может сбивать с толку. На самом деле действие (чтение или запись из/в коллекцию pool) выполняется не пользователем, а облачной функцией. А в облачной функции вы получаете uid вызывающего абонента (см. комментарий выше) и решаете, можете ли вы писать или читать в/из коллекции на основе этого uid. другими словами, облачная функция действует как сервер приложений или промежуточное программное обеспечение.

Renaud Tarnec 13.02.2023 19:19

Спасибо мастер. Я многому научился. Теперь я могу перенести много кода Function во Flutter. Я даже не знал, что Flutter может напрямую CRUD Firestore... Я думал, что мне нужен бэкенд для связи с Firestore DB. Теперь мне кажется яснее! Мой вопрос был закрыт, но еще раз спасибо.

ghchoi 14.02.2023 04:10

Другие вопросы по теме