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