Cloud Firestore Security Rules позволяют контролировать доступ к документам и коллекциям в вашей базе данных. Гибкий синтаксис правил позволяет создавать правила, соответствующие чему угодно, от всех операций записи во всю базу данных до операций над конкретным документом.
В этом руководстве описаны базовый синтаксис и структура правил безопасности. Сочетайте этот синтаксис с условиями правил безопасности для создания полных наборов правил.
Объявление об услугах и базе данных
Cloud Firestore Security Rules всегда начинаются со следующего заявления:
service cloud.firestore {
// The {database} wildcard allows the rules to reference any database,
// but these rules are only active on databases where they are explicitly deployed.
match /databases/{database}/documents {
// ...
}
}
Объявление service cloud.firestore ограничивает действие правил только Cloud Firestore , предотвращая конфликты между Cloud Firestore Security Rules и правилами для других продуктов, таких как Cloud Storage.
Объявление match /databases/{database}/documents указывает, что правила должны соответствовать любой базе данных Cloud Firestore в проекте. Хотя проект может содержать до 100 баз данных, в качестве базы данных по умолчанию назначается только первая созданная база данных.
Cloud Firestore Security Rules применяются отдельно для каждой указанной базы данных в вашем проекте. Это означает, что если вы создадите несколько баз данных, вам необходимо будет управлять правилами и развертывать их для каждой из них индивидуально. Подробные инструкции по развертыванию обновлений см. в разделе «Развертывание обновлений» .
Основные правила чтения/записи
Основные правила включают в себя оператор match указывающий путь к документу, и выражение allow определяющее, когда разрешено чтение указанных данных:
service cloud.firestore {
match /databases/{database}/documents {
// Match any document in the 'cities' collection
match /cities/{city} {
allow read: if <condition>;
allow write: if <condition>;
}
}
}
Все операторы match должны указывать на документы, а не на коллекции. Оператор match может указывать на конкретный документ, например, match /cities/SF , или использовать подстановочные знаки для указания на любой документ в указанном пути, например, match /cities/{city} .
В приведенном выше примере оператор match использует синтаксис подстановочного знака {city} . Это означает, что правило применяется к любому документу в коллекции cities , например /cities/SF или /cities/NYC . При оценке выражений allow в операторе match переменная city будет преобразована в имя документа города, например, SF или NYC .
Гранулярные операции
В некоторых ситуациях полезно разбить операции read и write на более мелкие. Например, ваше приложение может устанавливать разные условия для создания и удаления документов. Или вы можете разрешить чтение отдельных документов, но запретить большие запросы.
Правило read можно разбить на get и list , а правило write на create , update и delete .
service cloud.firestore {
match /databases/{database}/documents {
// A read rule can be divided into get and list rules
match /cities/{city} {
// Applies to single document read requests
allow get: if <condition>;
// Applies to queries and collection read requests
allow list: if <condition>;
}
// A write rule can be divided into create, update, and delete rules
match /cities/{city} {
// Applies to writes to nonexistent documents
allow create: if <condition>;
// Applies to writes to existing documents
allow update: if <condition>;
// Applies to delete operations
allow delete: if <condition>;
}
}
}
Иерархические данные
В Cloud Firestore данные организованы в коллекции документов, и каждый документ может расширять иерархию за счет подколлекций. Важно понимать, как правила безопасности взаимодействуют с иерархическими данными.
Рассмотрим ситуацию, когда каждый документ в коллекции cities содержит подколлекцию landmarks . Правила безопасности применяются только к соответствующему пути, поэтому средства контроля доступа, определенные для коллекции cities не применяются к подколлекции landmarks . Вместо этого напишите явные правила для управления доступом к подколлекциям:
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city} {
allow read, write: if <condition>;
// Explicitly define rules for the 'landmarks' subcollection
match /landmarks/{landmark} {
allow read, write: if <condition>;
}
}
}
}
При вложенных операторах match путь внутреннего оператора match всегда является относительным по отношению к пути внешнего оператора match . Поэтому следующие наборы правил эквивалентны:
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city} {
match /landmarks/{landmark} {
allow read, write: if <condition>;
}
}
}
}
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city}/landmarks/{landmark} {
allow read, write: if <condition>;
}
}
}
Рекурсивные подстановочные символы
Если вы хотите, чтобы правила применялись к произвольно глубокой иерархии, используйте рекурсивный синтаксис с подстановочными знаками {name=**} . Например:
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the cities collection as well as any document
// in a subcollection.
match /cities/{document=**} {
allow read, write: if <condition>;
}
}
}
При использовании рекурсивного синтаксиса подстановочных символов переменная подстановочного символа будет содержать весь соответствующий сегмент пути, даже если документ находится в глубоко вложенной подколлекции. Например, приведенные выше правила будут соответствовать документу, расположенному по адресу /cities/SF/landmarks/coit_tower , и значение переменной document будет SF/landmarks/coit_tower .
Однако следует отметить, что поведение рекурсивных подстановочных символов зависит от версии правил.
Версия 1
Правила безопасности по умолчанию используют версию 1. В версии 1 рекурсивные подстановочные знаки соответствуют одному или нескольким элементам пути. Они не соответствуют пустому пути, поэтому match /cities/{city}/{document=**} соответствует документам в подколлекциях, но не в коллекции cities , тогда как match /cities/{document=**} соответствует документам как в коллекции cities , так и в подколлекциях.
Рекурсивные подстановочные символы должны располагаться в конце оператора сопоставления.
Версия 2
В версии 2 правил безопасности рекурсивные подстановочные знаки соответствуют нулю или более элементам пути. match/cities/{city}/{document=**} соответствует документам в любых подколлекциях, а также документам в коллекции cities .
Для активации версии 2 необходимо добавить в начало правил безопасности rules_version = '2';
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the cities collection as well as any document
// in a subcollection.
match /cities/{city}/{document=**} {
allow read, write: if <condition>;
}
}
}
В одном операторе match можно использовать не более одного рекурсивного подстановочного знака, но во второй версии этот подстановочный знак можно разместить в любом месте оператора match. Например:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the songs collection group
match /{path=**}/songs/{song} {
allow read, write: if <condition>;
}
}
}
Если вы используете запросы к группам коллекций , необходимо использовать версию 2; см. раздел «Защита запросов к группам коллекций» .
Перекрывающиеся заявления о матче
Документ может соответствовать более чем одному условию match . В случае, если несколько выражений allow соответствуют запросу, доступ разрешается, если true хотя бы одно из следующих условий:
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the 'cities' collection.
match /cities/{city} {
allow read, write: if false;
}
// Matches any document in the 'cities' collection or subcollections.
match /cities/{document=**} {
allow read, write: if true;
}
}
}
В приведенном выше примере все операции чтения и записи в коллекцию cities будут разрешены, поскольку второе правило всегда true , даже если первое правило всегда false .
Ограничения правил безопасности
При работе с правилами безопасности учитывайте следующие ограничения:
| Лимит | Подробности |
|---|---|
Максимальное количество вызовов методов exists() , get() и getAfter() за один запрос. |
Превышение любого из этих пределов приведет к ошибке "Доступ запрещен". Некоторые запросы на доступ к документам могут кэшироваться, и кэшированные запросы не учитываются в лимитах. |
Максимальная глубина вложенных match соответствия | 10 |
Максимальная допустимая длина пути в сегментах внутри набора вложенных операторов match . | 100 |
Максимальное количество переменных для захвата пути, разрешенных в наборе вложенных операторов match . | 20 |
| Максимальная глубина вызовов функций | 20 |
| Максимальное количество аргументов функции | 7 |
Максимальное количество привязок переменных let на функцию | 10 |
| Максимальное количество рекурсивных или циклических вызовов функций | 0 (не разрешено) |
| Максимальное количество выражений, оцениваемых за один запрос. | 1000 |
| Максимальный размер набора правил | Наборы правил должны соответствовать двум ограничениям по размеру:
|
Следующие шаги
- Напишите собственные правила и условия безопасности .
- Ознакомьтесь со справочником правил безопасности .