Правила безопасности Firebase для ограничения доступа по всем путям, кроме одного?
Вопрос:
Как ограничить доступ ко всем, кроме одного, путям для различных коллекций топок верхнего уровня, представленных ниже?
Мы создаем схему данных в Firestore для поддержки приложения чата для учителей из нескольких школ.
Коллекции верхнего уровня включают:
/siteAdminUsers
/schools
/schools/{schoolId}/teachers
/schools/{schoolId}/chats
Ниже приведена настройка правил безопасности, которую мы сейчас пытаемся проверить, где мы проверяем:
- действительный идентификатор пользователя
- ожидаемое значение существует в переменной userClaim
request.auth.token.chatFlatList
Тем не менее, читатель для чтения /messages
блокируется.
Сообщение об ошибке:
FirebaseError: [code= access-denied]: отсутствует или недостаточно разрешений
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null
&& request.auth.token != null
&& request.auth.token.chatFlatList.val().contains($discussionId);
}
}
подробности
Мы используем облачные функции для всех операций чтения / записи данных, поэтому практически в каждом случае мы можем просто заблокировать доступ всех клиентов.
Единственным исключением являются обсуждения в чате, где нам нужно настроить прослушиватель снимков в мобильном клиенте, чтобы знать, когда появляются новые сообщения.
Примечания суб-коллекции:
В школе проводятся дискуссионные сессии для школьного персонала (учителей, администраторов и т. Д.).
/schools/{schoolId}/chats/{discussionId}
Где каждый дискуссионный документ содержит:
- список учителей участников
- Подколлекция для фактических сообщений, где каждый документ является отдельным опубликованным сообщением:
/schools/{schoolId}/chats/{discussionId}/messages
Код заявки пользователя из облачной функции
Просматривая журналы облачных функций, мы убедились, что устанавливается userClaim.
return firebaseAdmin
.auth()
.setCustomUserClaims(
uid, {
chatFlatList: 'id1 id2 id3'
}
);
ОБНОВЛЕНИЕ № 1
Попробовал следующий вариант, где правила пропускают / опускают проверку userClaim и auth.token.
Тем не менее, все еще та же ошибка разрешения.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null;
}
}
}
1 ответ
Я думаю, что проблема в том, что вы пишете правило для коллекции, называемой сообщениями.
Все заявления о совпадении должны указывать на документы, а не на коллекции. https://firebase.google.com/docs/firestore/security/rules-structure
Вы должны попытаться добавить /{document=**} после вашего пути к сообщениям, что-то вроде:
match /schools/{schoolId}/chats/{discussionId}/messages/{document=**} {
allow write: if false;
allow read: if request.auth != null;
}
Это сработало для меня, если я хотел прочитать и записать всю коллекцию, но не одну коллекцию с именем "backStage";
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{collection}/{document} {
allow read: if true
allow write: if (collection != "backStage");
}
}
}
Вот решение (кажется, работает), которое включает в себя проверку на chatFlatList
переменная заявки пользователя (из исходного вопроса) для подстроки:
match /schools/{schoolId}/chats/{discussionId}/messages {
allow write: if false;
allow read: if request.auth != null
&& request.auth.token.chatFlatList.matches(discussionId);
}
Понял это благодаря:
Правила хранения Firebase на основе пользовательских параметров
- Здесь пост показывает, что нет никакого
$
запись для доступа к пути вар. Я помню, как видел это в примере кода с правилами безопасности - может быть, это относится к уровням базы данных?
- Здесь пост показывает, что нет никакого
https://firebase.google.com/docs/reference/security/storage/
https://regex-golang.appspot.com/assets/html/index.html
- Попробуем несколько примеров входных данных, чтобы понять, как создавать регулярные выражения.