Cloud Firestore Security Rules позволяют вам контролировать доступ к документам и коллекциям в вашей базе данных. Гибкий синтаксис правил позволяет создавать правила, соответствующие чему угодно: от всех операций записи во всю базу данных до операций над конкретным документом.
В этом руководстве описываются основной синтаксис и структура правил безопасности. Объедините этот синтаксис с условиями правил безопасности, чтобы создать полные наборы правил.
Декларация службы и базы данных
Cloud Firestore Security Rules всегда начинаются со следующего объявления:
service cloud.firestore {
match /databases/{database}/documents {
// ...
}
}
Объявление service cloud.firestore
распространяет правила на Cloud Firestore , предотвращая конфликты между Cloud Firestore Security Rules и правилами для других продуктов, таких как Cloud Storage.
Объявление match /databases/{database}/documents
указывает, что правила должны соответствовать любой базе данных Cloud Firestore в проекте. В настоящее время каждый проект имеет только одну базу данных с именем (default)
.
Основные правила чтения/записи
Основные правила состоят из оператора 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 /cities/SF
или использовать подстановочные знаки для указания на любой документ по указанному пути, как в match /cities/{city}
.
В приведенном выше примере оператор сопоставления использует синтаксис подстановочного знака {city}
. Это означает, что правило применяется к любому документу в коллекции cities
, например /cities/SF
или /cities/NYC
. При оценке allow
выражений в операторе сопоставления переменная 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>;
}
}
}
Вы можете использовать не более одного рекурсивного подстановочного знака для каждого оператора сопоставления, но в версии 2 вы можете разместить этот подстановочный знак в любом месте оператора сопоставления. Например:
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 |
Максимальный размер набора правил | Наборы правил должны подчиняться двум ограничениям по размеру:
|
Следующие шаги
- Напишите условия пользовательских правил безопасности .
- Прочтите справочник правил безопасности .