Firebase Security Rules используют гибкие, мощные, настраиваемые языки, поддерживающие широкий диапазон сложности и детализации. Вы можете сделать свои Rules настолько конкретными или общими, насколько это необходимо для вашего приложения. Правила Realtime Database используют синтаксис, похожий на JavaScript в структуре JSON. Правила Cloud Firestore и Cloud Storage используют язык, основанный на Common Expression Language (CEL) , который построен на CEL с операторами match
и allow
, поддерживающими условно предоставленный доступ.
Однако, поскольку это пользовательские языки, обучение им требует времени. Используйте это руководство, чтобы лучше понять язык Rules и глубже изучить более сложные правила.
Выберите продукт, чтобы узнать больше о его правилах.
Базовая структура
Cloud Firestore
Firebase Security Rules в Cloud Firestore и Cloud Storage используют следующую структуру и синтаксис:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
При разработке правил важно понимать следующие ключевые концепции:
- Запрос: Метод или методы, вызываемые в операторе
allow
. Это методы, запуск которых вы разрешаете. Стандартные методы:get
,list
,create
,update
иdelete
. Вспомогательные методыread
иwrite
обеспечивают широкий доступ для чтения и записи к указанной базе данных или пути к хранилищу. - Путь: база данных или место хранения, представленное в виде пути URI.
- Правило:
allow
оператор, включающий условие, разрешающее запрос, если оно оценивается как истинное.
Ниже каждая из этих концепций описана более подробно.
Cloud Storage
Firebase Security Rules в Cloud Firestore и Cloud Storage используют следующую структуру и синтаксис:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
При разработке правил важно понимать следующие ключевые концепции:
- Запрос: Метод или методы, вызываемые в операторе
allow
. Это методы, запуск которых вы разрешаете. Стандартные методы:get
,list
,create
,update
иdelete
. Вспомогательные методыread
иwrite
обеспечивают широкий доступ для чтения и записи к указанной базе данных или пути к хранилищу. - Путь: база данных или место хранения, представленное в виде пути URI.
- Правило:
allow
оператор, включающий условие, разрешающее запрос, если оно оценивается как истинное.
Ниже каждая из этих концепций описана более подробно.
Realtime Database
В Realtime Database Firebase Security Rules состоят из выражений, подобных JavaScript, содержащихся в документе JSON.
Они используют следующий синтаксис:
{
"rules": {
"<<path>>": {
// Allow the request if the condition for each method is true.
".read": <<condition>>,
".write": <<condition>>,
".validate": <<condition>>
}
}
}
Правило содержит три основных элемента:
- Путь: расположение базы данных. Он отражает JSON-структуру вашей базы данных.
- Запрос: это методы, которые правило использует для предоставления доступа. Правила
read
иwrite
предоставляют широкий доступ на чтение и запись, в то время как правилаvalidate
выполняют функцию вторичной проверки для предоставления доступа на основе входящих или существующих данных. - Условие: Условие, разрешающее запрос, если оно оценивается как истинное.
Конструкции правил
Cloud Firestore
Основные элементы правила в Cloud Firestore и Cloud Storage следующие:
- Объявление
service
: объявляет продукт Firebase, к которому применяются правила. - Блок
match
: определяет путь в базе данных или хранилище, к которому применяются правила. - Оператор
allow
: предоставляет условия предоставления доступа, различающиеся по методам. Поддерживаются следующие методы:get
,list
,create
,update
,delete
, а также вспомогательные методыread
иwrite
. - Необязательные объявления
function
: предоставляют возможность объединять и оборачивать условия для использования в нескольких правилах.
service
содержит один или несколько блоков match
с операторами allow
, которые задают условия предоставления доступа к запросам. Переменные request
и resource
доступны для использования в условиях правил. Язык Firebase Security Rules также поддерживает объявления function
.
Версия синтаксиса
В операторе syntax
указана версия языка правил Firebase, используемая для написания исходного кода. Последняя версия языка — v2
.
rules_version = '2';
service cloud.firestore {
...
}
Если оператор rules_version
не указан, ваши правила будут оцениваться с использованием движка v1
.
Услуга
Объявление service
определяет, к какому продукту или сервису Firebase применяются ваши правила. В каждый исходный файл можно включить только одно объявление service
.
Cloud Firestore
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Cloud Storage
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Если вы определяете правила для Cloud Firestore и Cloud Storage с помощью Firebase CLI, вам придется хранить их в отдельных файлах.
Соответствовать
Блок match
объявляет шаблон path
, который сопоставляется с путём для запрошенной операции (входящий request.path
). Тело match
должно содержать один или несколько вложенных блоков match
, allow
разрешения или объявлений function
. Путь во вложенных блоках match
указывается относительно пути в родительском блоке match
.
Шаблон path
— это имя, похожее на имя каталога, которое может включать переменные или подстановочные знаки. Шаблон path
допускает сопоставление сегментов с одним и несколькими путями. Все переменные, связанные с path
, видны в области match
или любой вложенной области, где объявлен path
.
Совпадения с шаблоном path
могут быть частичными или полными:
- Частичное совпадение: шаблон
path
представляет собой префиксное совпадениеrequest.path
. - Полные совпадения: шаблон
path
соответствует всемуrequest.path
.
При полном совпадении проверяются правила внутри блока. При частичном совпадении проверяются правила вложенного match
, чтобы определить, сможет ли какой-либо вложенный path
завершить совпадение.
Правила в каждом полном match
оцениваются, чтобы определить, разрешать ли запрос. Если хотя бы одно совпадающее правило разрешает доступ, запрос разрешается. Если ни одно совпадающее правило не разрешает доступ, запрос отклоняется.
// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
// Partial match.
match /example/{singleSegment} { // `singleSegment` == 'hello'
allow write; // Write rule not evaluated.
// Complete match.
match /nested/path { // `singleSegment` visible in scope.
allow read; // Read rule is evaluated.
}
}
// Complete match.
match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
allow read; // Read rule is evaluated.
}
}
Как показано в примере выше, объявления path
поддерживают следующие переменные:
- Односегментный подстановочный знак: подстановочная переменная объявляется в пути путём заключения переменной в фигурные скобки:
{variable}
. Эта переменная доступна внутри оператораmatch
какstring
. - Рекурсивный подстановочный знак: Рекурсивный, или многосегментный, подстановочный знак соответствует нескольким сегментам пути, расположенным на пути или ниже него. Этот подстановочный знак соответствует всем путям ниже указанного вами местоположения. Вы можете объявить его, добавив строку
=**
в конец переменной сегмента:{variable=**}
. Эта переменная доступна внутри оператораmatch
как объектpath
.
Позволять
Блок match
содержит один или несколько операторов allow
. Это ваши фактические правила. Вы можете применить правила allow
к одному или нескольким методам. Условия оператора allow
должны быть истинными, чтобы Cloud Firestore или Cloud Storage разрешили любой входящий запрос. Вы также можете писать операторы allow
без условий, например, allow read
. Однако, если оператор allow
не содержит условия, он всегда разрешает запрос для этого метода.
Если какое-либо из правил allow
для метода выполнено, запрос разрешается. Кроме того, если более широкое правило разрешает доступ, Rules разрешают доступ и игнорируют любые более детальные правила, которые могут ограничивать доступ.
Рассмотрим следующий пример, где любой пользователь может читать или удалять любые свои файлы. Более детальное правило разрешает запись только в том случае, если пользователь, запрашивающий запись, является владельцем файла и файл имеет формат PNG. Пользователь может удалить любые файлы в подпути, даже если они не являются файлами PNG, поскольку предыдущее правило это разрешает.
service firebase.storage {
// Allow the requestor to read or delete any resource on a path under the
// user directory.
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// Allow the requestor to create or update their own images.
// When 'request.method' == 'delete' this rule and the one matching
// any path under the user directory would both match and the `delete`
// would be permitted.
match /users/{userId}/images/{imageId} {
// Whether to permit the request depends on the logical OR of all
// matched rules. This means that even if this rule did not explicitly
// allow the 'delete' the earlier rule would have.
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
Метод
Каждый allow
оператор включает метод, который предоставляет доступ для входящих запросов того же метода.
Метод | Тип запроса |
---|---|
Удобные методы | |
read | Любой тип запроса на чтение |
write | Любой тип запроса на запись |
Стандартные методы | |
get | Запросы на чтение отдельных документов или файлов |
list | Чтение запросов на запросы и коллекции |
create | Напишите новые документы или файлы |
update | Запись в существующие документы базы данных или обновление метаданных файлов |
delete | Удалить данные |
Не допускается перекрытие методов чтения в одном и том же блоке match
или конфликтующих методов записи в одном и том же объявлении path
.
Например, следующие правила не будут работать:
service bad.example {
match /rules/with/overlapping/methods {
// This rule allows reads to all authenticated users
allow read: if request.auth != null;
match another/subpath {
// This secondary, more specific read rule causes an error
allow get: if request.auth != null && request.auth.uid == "me";
// Overlapping write methods in the same path cause an error as well
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
Функция
По мере усложнения правил безопасности может возникнуть необходимость обернуть наборы условий в функции, которые можно будет повторно использовать в вашем наборе правил. Правила безопасности поддерживают пользовательские функции. Синтаксис пользовательских функций немного похож на JavaScript, но функции правил безопасности написаны на предметно-ориентированном языке, который имеет ряд важных ограничений:
- Функции могут содержать только один оператор
return
. Они не могут содержать никакой дополнительной логики. Например, они не могут выполнять циклы или вызывать внешние сервисы. - Функции могут автоматически получать доступ к функциям и переменным из области действия, в которой они определены. Например, функция, определённая в области действия
service cloud.firestore
, имеет доступ к переменнойresource
и встроенным функциям, таким какget()
иexists()
. - Функции могут вызывать другие функции, но не могут быть рекурсивными. Общая глубина стека вызовов ограничена 20.
- В правилах версии
v2
функции могут определять переменные с помощью ключевого словаlet
. Функции могут иметь до 10 привязок let, но должны завершаться оператором return.
Функция определяется ключевым словом function
и принимает ноль или более аргументов. Например, вы можете объединить два типа условий, использованных в примерах выше, в одну функцию:
service cloud.firestore {
match /databases/{database}/documents {
// True if the user is signed in or the requested data is 'public'
function signedInOrPublic() {
return request.auth.uid != null || resource.data.visibility == 'public';
}
match /cities/{city} {
allow read, write: if signedInOrPublic();
}
match /users/{user} {
allow read, write: if signedInOrPublic();
}
}
}
Вот пример, демонстрирующий аргументы функции и присваивание операторов let. Операторы присваивания let должны быть разделены точкой с запятой.
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
Обратите внимание, как назначение isAdmin
принудительно выполняет поиск по коллекции admins. Для ленивой оценки без необходимости поиска воспользуйтесь сокращённой природой сравнений &&
(AND) и ||
(OR), чтобы вызывать вторую функцию только в том случае, если isAuthor
имеет значение true (для сравнений &&
) или false (для сравнений ||
).
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
// `||` is short-circuiting; isAdmin called only if isAuthor == false.
return isAuthor || isAdmin(userId);
}
Использование функций в правилах безопасности делает их более удобными для поддержки по мере роста сложности правил.
Cloud Storage
Основные элементы правила в Cloud Firestore и Cloud Storage следующие:
- Объявление
service
: объявляет продукт Firebase, к которому применяются правила. - Блок
match
: определяет путь в базе данных или хранилище, к которому применяются правила. - Оператор
allow
: предоставляет условия предоставления доступа, различающиеся по методам. Поддерживаются следующие методы:get
,list
,create
,update
,delete
, а также вспомогательные методыread
иwrite
. - Необязательные объявления
function
: предоставляют возможность объединять и оборачивать условия для использования в нескольких правилах.
service
содержит один или несколько блоков match
с операторами allow
, которые задают условия предоставления доступа к запросам. Переменные request
и resource
доступны для использования в условиях правил. Язык Firebase Security Rules также поддерживает объявления function
.
Версия синтаксиса
В операторе syntax
указана версия языка правил Firebase, используемая для написания исходного кода. Последняя версия языка — v2
.
rules_version = '2';
service cloud.firestore {
...
}
Если оператор rules_version
не указан, ваши правила будут оцениваться с использованием движка v1
.
Услуга
Объявление service
определяет, к какому продукту или сервису Firebase применяются ваши правила. В каждый исходный файл можно включить только одно объявление service
.
Cloud Firestore
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Cloud Storage
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Если вы определяете правила для Cloud Firestore и Cloud Storage с помощью Firebase CLI, вам придется хранить их в отдельных файлах.
Соответствовать
Блок match
объявляет шаблон path
, который сопоставляется с путём для запрошенной операции (входящий request.path
). Тело match
должно содержать один или несколько вложенных блоков match
, allow
разрешения или объявлений function
. Путь во вложенных блоках match
указывается относительно пути в родительском блоке match
.
Шаблон path
— это имя, похожее на имя каталога, которое может включать переменные или подстановочные знаки. Шаблон path
допускает сопоставление сегментов с одним и несколькими путями. Все переменные, связанные с path
, видны в области match
или любой вложенной области, где объявлен path
.
Совпадения с шаблоном path
могут быть частичными или полными:
- Частичное совпадение: шаблон
path
представляет собой префиксное совпадениеrequest.path
. - Полные совпадения: шаблон
path
соответствует всемуrequest.path
.
При полном совпадении проверяются правила внутри блока. При частичном совпадении проверяются правила вложенного match
, чтобы определить, сможет ли какой-либо вложенный path
завершить совпадение.
Правила в каждом полном match
оцениваются, чтобы определить, разрешать ли запрос. Если хотя бы одно совпадающее правило разрешает доступ, запрос разрешается. Если ни одно совпадающее правило не разрешает доступ, запрос отклоняется.
// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
// Partial match.
match /example/{singleSegment} { // `singleSegment` == 'hello'
allow write; // Write rule not evaluated.
// Complete match.
match /nested/path { // `singleSegment` visible in scope.
allow read; // Read rule is evaluated.
}
}
// Complete match.
match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
allow read; // Read rule is evaluated.
}
}
Как показано в примере выше, объявления path
поддерживают следующие переменные:
- Односегментный подстановочный знак: подстановочная переменная объявляется в пути путём заключения переменной в фигурные скобки:
{variable}
. Эта переменная доступна внутри оператораmatch
какstring
. - Рекурсивный подстановочный знак: Рекурсивный, или многосегментный, подстановочный знак соответствует нескольким сегментам пути, расположенным на пути или ниже него. Этот подстановочный знак соответствует всем путям ниже указанного вами местоположения. Вы можете объявить его, добавив строку
=**
в конец переменной сегмента:{variable=**}
. Эта переменная доступна внутри оператораmatch
как объектpath
.
Позволять
Блок match
содержит один или несколько операторов allow
. Это ваши фактические правила. Вы можете применить правила allow
к одному или нескольким методам. Условия оператора allow
должны быть истинными, чтобы Cloud Firestore или Cloud Storage разрешили любой входящий запрос. Вы также можете писать операторы allow
без условий, например, allow read
. Однако, если оператор allow
не содержит условия, он всегда разрешает запрос для этого метода.
Если какое-либо из правил allow
для метода выполнено, запрос разрешается. Кроме того, если более широкое правило разрешает доступ, Rules разрешают доступ и игнорируют любые более детальные правила, которые могут ограничивать доступ.
Рассмотрим следующий пример, где любой пользователь может читать или удалять любые свои файлы. Более детальное правило разрешает запись только в том случае, если пользователь, запрашивающий запись, является владельцем файла и файл имеет формат PNG. Пользователь может удалить любые файлы в подпути, даже если они не являются файлами PNG, поскольку предыдущее правило это разрешает.
service firebase.storage {
// Allow the requestor to read or delete any resource on a path under the
// user directory.
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// Allow the requestor to create or update their own images.
// When 'request.method' == 'delete' this rule and the one matching
// any path under the user directory would both match and the `delete`
// would be permitted.
match /users/{userId}/images/{imageId} {
// Whether to permit the request depends on the logical OR of all
// matched rules. This means that even if this rule did not explicitly
// allow the 'delete' the earlier rule would have.
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
Метод
Каждый allow
оператор включает метод, который предоставляет доступ для входящих запросов того же метода.
Метод | Тип запроса |
---|---|
Удобные методы | |
read | Любой тип запроса на чтение |
write | Любой тип запроса на запись |
Стандартные методы | |
get | Запросы на чтение отдельных документов или файлов |
list | Чтение запросов на запросы и коллекции |
create | Напишите новые документы или файлы |
update | Запись в существующие документы базы данных или обновление метаданных файлов |
delete | Удалить данные |
Не допускается перекрытие методов чтения в одном и том же блоке match
или конфликтующих методов записи в одном и том же объявлении path
.
Например, следующие правила не будут работать:
service bad.example {
match /rules/with/overlapping/methods {
// This rule allows reads to all authenticated users
allow read: if request.auth != null;
match another/subpath {
// This secondary, more specific read rule causes an error
allow get: if request.auth != null && request.auth.uid == "me";
// Overlapping write methods in the same path cause an error as well
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
Функция
По мере усложнения правил безопасности может возникнуть необходимость обернуть наборы условий в функции, которые можно будет повторно использовать в вашем наборе правил. Правила безопасности поддерживают пользовательские функции. Синтаксис пользовательских функций немного похож на JavaScript, но функции правил безопасности написаны на предметно-ориентированном языке, который имеет ряд важных ограничений:
- Функции могут содержать только один оператор
return
. Они не могут содержать никакой дополнительной логики. Например, они не могут выполнять циклы или вызывать внешние сервисы. - Функции могут автоматически получать доступ к функциям и переменным из области действия, в которой они определены. Например, функция, определённая в области действия
service cloud.firestore
, имеет доступ к переменнойresource
и встроенным функциям, таким какget()
иexists()
. - Функции могут вызывать другие функции, но не могут быть рекурсивными. Общая глубина стека вызовов ограничена 20.
- В правилах версии
v2
функции могут определять переменные с помощью ключевого словаlet
. Функции могут иметь до 10 привязок let, но должны завершаться оператором return.
Функция определяется ключевым словом function
и принимает ноль или более аргументов. Например, вы можете объединить два типа условий, использованных в примерах выше, в одну функцию:
service cloud.firestore {
match /databases/{database}/documents {
// True if the user is signed in or the requested data is 'public'
function signedInOrPublic() {
return request.auth.uid != null || resource.data.visibility == 'public';
}
match /cities/{city} {
allow read, write: if signedInOrPublic();
}
match /users/{user} {
allow read, write: if signedInOrPublic();
}
}
}
Вот пример, демонстрирующий аргументы функции и присваивание операторов let. Операторы присваивания let должны быть разделены точкой с запятой.
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
Обратите внимание, как назначение isAdmin
принудительно выполняет поиск по коллекции admins. Для ленивой оценки без необходимости поиска воспользуйтесь сокращённой природой сравнений &&
(AND) и ||
(OR), чтобы вызывать вторую функцию только в том случае, если isAuthor
имеет значение true (для сравнений &&
) или false (для сравнений ||
).
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
// `||` is short-circuiting; isAdmin called only if isAuthor == false.
return isAuthor || isAdmin(userId);
}
Использование функций в правилах безопасности делает их более удобными для поддержки по мере роста сложности правил.
Realtime Database
Как указано выше, Rules Realtime Database включают три основных элемента: расположение базы данных как зеркало JSON-структуры базы данных, тип запроса и условие предоставления доступа.
Расположение базы данных
Структура ваших правил должна соответствовать структуре данных, хранящихся в вашей базе данных. Например, в чат-приложении со списком сообщений данные могут выглядеть следующим образом:
{
"messages": {
"message0": {
"content": "Hello",
"timestamp": 1405704370369
},
"message1": {
"content": "Goodbye",
"timestamp": 1405704395231
},
...
}
}
Ваши правила должны отражать эту структуру. Например:
{
"rules": {
"messages": {
"$message": {
// only messages from the last ten minutes can be read
".read": "data.child('timestamp').val() > (now - 600000)",
// new messages must have a string content and a number timestamp
".validate": "newData.hasChildren(['content', 'timestamp']) &&
newData.child('content').isString() &&
newData.child('timestamp').isNumber()"
}
}
}
}
Как показано в примере выше, Rules Realtime Database поддерживают переменную $location
для сопоставления сегментов пути. Используйте префикс $
перед сегментом пути, чтобы сопоставить правило со всеми дочерними узлами на пути.
{
"rules": {
"rooms": {
// This rule applies to any child of /rooms/, the key for each room id
// is stored inside $room_id variable for reference
"$room_id": {
"topic": {
// The room's topic can be changed if the room id has "public" in it
".write": "$room_id.contains('public')"
}
}
}
}
}
Вы также можете использовать $variable
параллельно с константными именами путей.
{
"rules": {
"widget": {
// a widget can have a title or color attribute
"title": { ".validate": true },
"color": { ".validate": true },
// but no other child paths are allowed
// in this case, $other means any key excluding "title" and "color"
"$other": { ".validate": false }
}
}
}
Метод
В Realtime Database существует три типа правил. Два из них — read
и write
— применяются к методу входящего запроса. Правило validate
проверяет структуру данных, а также формат и содержание данных. Rules запускают правила .validate
после проверки того, что правило .write
предоставляет доступ.
Типы правил | |
---|---|
.читать | Описывает, разрешено ли пользователям читать данные и когда это возможно. |
.писать | Описывает, разрешено ли записывать данные и когда это разрешено. |
.валидировать | Определяет, как будет выглядеть правильно отформатированное значение, имеет ли оно дочерние атрибуты и тип данных. |
По умолчанию, если нет разрешающего правила, доступ по пути запрещен.
Условия строительства
Cloud Firestore
Условие — это логическое выражение, определяющее, следует ли разрешить или запретить конкретную операцию. Переменные request
и resource
предоставляют контекст для этих условий.
Переменная request
Переменная request
включает в себя следующие поля и соответствующую информацию:
request.auth
Веб-токен JSON (JWT), содержащий учётные данные аутентификации из Firebase Authentication . Токен auth
содержит набор стандартных утверждений и любых пользовательских утверждений, создаваемых с помощью Firebase Authentication . Узнайте больше о Firebase Security Rules и Authentication Firebase .
request.method
Метод request.method
может быть любым стандартным или пользовательским. Вспомогательные методы read
и write
также существуют для упрощения правил записи, применяемых ко всем стандартным методам, доступным только для чтения или только для записи соответственно.
request.params
В request.params
включены все данные, не относящиеся непосредственно к request.resource
, которые могут быть полезны для оценки. На практике эта карта должна быть пустой для всех стандартных методов и содержать нересурсные данные для пользовательских методов. Сервисы должны быть осторожны, чтобы не переименовывать и не изменять тип ключей и значений, представленных в качестве параметров.
request.path
request.path
— это путь к целевому resource
. Путь указывается относительно сервиса. Сегменты пути, содержащие небезопасные для URL символы, такие как /
кодируются в URL.
Переменная resource
resource
— это текущее значение в сервисе, представленное в виде карты пар «ключ-значение». Ссылка на resource
в условии приведёт к максимум одному чтению значения из сервиса. Этот поиск будет учитываться в любой квоте сервиса для ресурса. Для запросов get
resource
будет учитываться в квоте только при отказе.
Операторы и приоритет операторов
Используйте представленную ниже таблицу в качестве справочной информации по операторам и их приоритетам в Rules для Cloud Firestore и Cloud Storage .
Даны произвольные выражения a
и b
, поле f
и индекс i
.
Оператор | Описание | Ассоциативность |
---|---|---|
a[i] a() af | Индекс, вызов, доступ к полю | слева направо | !a -a | Унарное отрицание | справа налево |
a/ba%ba*b | Мультипликативные операторы | слева направо |
a+b ab | Аддитивные операторы | слева направо |
a>ba>=ba | Реляционные операторы | слева направо |
a in b | Наличие в списке или на карте | слева направо |
a is type | Сравнение типов, где type может быть bool, int, float, number, string, list, map, timestamp, duration, path или latlng | слева направо |
a==ba!=b | Операторы сравнения | слева направо | a && b | Условное И | слева направо |
a || b | Условное ИЛИ | слева направо |
a ? true_value : false_value | Троичное выражение | слева направо |
Cloud Storage
Условие — это логическое выражение, определяющее, следует ли разрешить или запретить конкретную операцию. Переменные request
и resource
предоставляют контекст для этих условий.
Переменная request
Переменная request
включает в себя следующие поля и соответствующую информацию:
request.auth
Веб-токен JSON (JWT), содержащий учётные данные аутентификации из Firebase Authentication . Токен auth
содержит набор стандартных утверждений и любых пользовательских утверждений, создаваемых с помощью Firebase Authentication . Узнайте больше о Firebase Security Rules и Authentication Firebase .
request.method
Метод request.method
может быть любым стандартным или пользовательским. Вспомогательные методы read
и write
также существуют для упрощения правил записи, применяемых ко всем стандартным методам, доступным только для чтения или только для записи соответственно.
request.params
В request.params
включены все данные, не относящиеся непосредственно к request.resource
, которые могут быть полезны для оценки. На практике эта карта должна быть пустой для всех стандартных методов и содержать нересурсные данные для пользовательских методов. Сервисы должны быть осторожны, чтобы не переименовывать и не изменять тип ключей и значений, представленных в качестве параметров.
request.path
request.path
— это путь к целевому resource
. Путь указывается относительно сервиса. Сегменты пути, содержащие небезопасные для URL символы, такие как /
кодируются в URL.
Переменная resource
resource
— это текущее значение в сервисе, представленное в виде карты пар «ключ-значение». Ссылка на resource
в условии приведёт к максимум одному чтению значения из сервиса. Этот поиск будет учитываться в любой квоте сервиса для ресурса. Для запросов get
resource
будет учитываться в квоте только при отказе.
Операторы и приоритет операторов
Используйте представленную ниже таблицу в качестве справочной информации по операторам и их приоритетам в Rules для Cloud Firestore и Cloud Storage .
Даны произвольные выражения a
и b
, поле f
и индекс i
.
Оператор | Описание | Ассоциативность |
---|---|---|
a[i] a() af | Индекс, вызов, доступ к полю | слева направо | !a -a | Унарное отрицание | справа налево |
a/ba%ba*b | Мультипликативные операторы | слева направо |
a+b ab | Аддитивные операторы | слева направо |
a>ba>=ba | Реляционные операторы | слева направо |
a in b | Наличие в списке или на карте | слева направо |
a is type | Сравнение типов, где type может быть bool, int, float, number, string, list, map, timestamp, duration, path или latlng | слева направо |
a==ba!=b | Операторы сравнения | слева направо | a && b | Условное И | слева направо |
a || b | Условное ИЛИ | слева направо |
a ? true_value : false_value | Троичное выражение | слева направо |
Realtime Database
Условие — это логическое выражение, определяющее, следует ли разрешить или запретить конкретную операцию. Эти условия можно определить в Rules Realtime Database следующими способами.
Предопределенные переменные
Существует ряд полезных предопределенных переменных, к которым можно получить доступ внутри определения правила. Вот краткое описание каждой из них:
Предопределенные переменные | |
---|---|
сейчас | Текущее время в миллисекундах с начала эпохи Linux. Это особенно удобно для проверки временных меток, созданных с помощью firebase.database.ServerValue.TIMESTAMP из SDK. |
корень | RuleDataSnapshot, представляющий корневой путь в базе данных Firebase в том виде, в котором он существовал до попытки выполнения операции. |
новые данные | Снимок данных RuleDataSnapshot , представляющий данные в том виде, в котором они будут существовать после выполнения операции. Он включает в себя новые записываемые данные и существующие данные. |
данные | RuleDataSnapshot, представляющий данные в том виде, в котором они существовали до попытки выполнения операции. |
$ переменные | Подстановочный путь, используемый для представления идентификаторов и динамических дочерних ключей. |
аутентификация | Представляет собой полезную нагрузку токена аутентифицированного пользователя. |
Эти переменные можно использовать в любом месте правил. Например, приведенные ниже правила безопасности гарантируют, что данные, записываемые в узел /foo/
, должны быть строкой длиной менее 100 символов:
{ "rules": { "foo": { // /foo is readable by the world ".read": true, // /foo is writable by the world ".write": true, // data written to /foo must be a string less than 100 characters ".validate": "newData.isString() && newData.val().length < 100" } } }
Правила на основе данных
Любые данные из вашей базы данных могут быть использованы в ваших правилах. Используя предопределённые переменные root
, data
и newData
, вы можете получить доступ к любому пути, который существовал бы до или после события записи.
Рассмотрим этот пример, который разрешает операции записи до тех пор, пока значение узла /allow_writes/
равно true
, родительский узел не имеет установленного флага readOnly
и в новых записанных данных есть дочерний узел с именем foo
:
".write": "root.child('allow_writes').val() === true && !data.parent().child('readOnly').exists() && newData.child('foo').exists()"
Правила на основе запросов
Хотя правила нельзя использовать в качестве фильтров, вы можете ограничить доступ к подмножествам данных, используя параметры запроса в правилах. Используйте выражения query.
в правилах, чтобы предоставить доступ на чтение или запись на основе параметров запроса.
Например, следующее правило на основе запроса использует правила безопасности на основе пользователя и правила на основе запроса, чтобы ограничить доступ к данным в коллекции baskets
только теми корзинами покупок, которыми владеет активный пользователь:
"baskets": {
".read": "auth.uid !== null &&
query.orderByChild === 'owner' &&
query.equalTo === auth.uid" // restrict basket access to owner of basket
}
Следующий запрос, включающий параметры запроса в правиле, будет выполнен успешно:
db.ref("baskets").orderByChild("owner")
.equalTo(auth.currentUser.uid)
.on("value", cb) // Would succeed
Однако запросы, не включающие параметры в правило, будут завершаться ошибкой PermissionDenied
:
db.ref("baskets").on("value", cb) // Would fail with PermissionDenied
Вы также можете использовать правила на основе запросов, чтобы ограничить объем данных, загружаемых клиентом посредством операций чтения.
Например, следующее правило ограничивает доступ для чтения только первыми 1000 результатами запроса в порядке приоритета:
messages: {
".read": "query.orderByKey &&
query.limitToFirst <= 1000"
}
// Example queries:
db.ref("messages").on("value", cb) // Would fail with PermissionDenied
db.ref("messages").limitToFirst(1000)
.on("value", cb) // Would succeed (default order by key)
Следующие выражения query.
доступны в Realtime Database Security Rules .
Выражения правил на основе запросов | ||
---|---|---|
Выражение | Тип | Описание |
запрос.orderByKey запрос.orderByPriority запрос.orderByValue | булев | True для запросов, упорядоченных по ключу, приоритету или значению. False в противном случае. |
запрос.orderByChild | нить нулевой | Используйте строку для указания относительного пути к дочернему узлу. Например, query.orderByChild === "address/zip" . Если запрос не упорядочен по дочернему узлу, это значение равно NULL. |
query.startAt query.endAt запрос.равно | нить число булев нулевой | Извлекает границы выполняемого запроса или возвращает null, если набор границ не установлен. |
query.limitToFirst query.limitToLast | число нулевой | Возвращает ограничение на выполняемый запрос или возвращает значение null, если ограничение не установлено. |
Операторы
Rules Realtime Database поддерживают ряд операторов , которые можно использовать для объединения переменных в условном выражении. Полный список операторов см. в справочной документации .
Создание условий
Фактические условия будут зависеть от предоставляемого вами доступа. Rules намеренно обеспечивают высокую степень гибкости, поэтому правила вашего приложения могут быть настолько простыми или сложными, насколько вам нужно.
Инструкции по созданию простых, готовых к использованию Rules см. в разделе Основные правила безопасности .