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 приводит к принудительному поиску в коллекции администраторов. Для отложенной оценки без необходимости ненужных поисков воспользуйтесь преимуществами механизма сокращения времени выполнения сравнений && (AND) и || (OR), чтобы вызывать вторую функцию только в том случае, если isAuthor истинно (для сравнений && ) или ложно (для сравнений || ).
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 приводит к принудительному поиску в коллекции администраторов. Для отложенной оценки без необходимости ненужных поисков воспользуйтесь преимуществами механизма сокращения времени выполнения сравнений && (AND) и || (OR), чтобы вызывать вторую функцию только в том случае, если isAuthor истинно (для сравнений && ) или ложно (для сравнений || ).
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 предоставляет доступ.
| Типы правил | |
|---|---|
| .читать | Указывает, разрешено ли пользователям читать данные и когда это разрешено. |
| .писать | Указывает, разрешено ли и когда разрешается запись данных. |
| .validate | Определяет, как будет выглядеть правильно отформатированное значение, имеет ли оно дочерние атрибуты и тип данных. |
По умолчанию, если нет правила, разрешающего доступ по указанному пути, доступ по нему запрещается.
Условия строительства
Cloud Firestore
Условие — это логическое выражение, определяющее, следует ли разрешить или запретить конкретную операцию. Переменные request и resource предоставляют контекст для этих условий.
Переменная request
Переменная request включает следующие поля и соответствующую информацию:
request.auth
JSON Web Token (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 Web Token (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 .
| Выражения правил на основе запросов | ||
|---|---|---|
| Выражение | Тип | Описание |
| query.orderByKey query.orderByPriority query.orderByValue | логический | Значение true для запросов, упорядоченных по ключу, приоритету или значению. В противном случае — false. |
| query.orderByChild | нить нулевой | Для представления относительного пути к дочернему узлу используйте строку. Например, query.orderByChild === "address/zip" . Если запрос не упорядочен по дочернему узлу, это значение будет равно null. |
| запрос.начало запрос.конецВ query.equalTo | нить число логический нулевой | Получает границы выполняемого запроса или возвращает null, если границы не заданы. |
| query.limitToFirst query.limitToLast | число нулевой | Получает лимит для выполняемого запроса или возвращает null, если лимит не установлен. |
Операторы
Rules Realtime Database поддерживают ряд операторов , которые можно использовать для объединения переменных в операторе условия. Полный список операторов см. в справочной документации .
Создание условий
Фактические условия будут зависеть от того, какой доступ вы хотите предоставить. Rules намеренно обеспечивают огромную гибкость, поэтому правила вашего приложения в конечном итоге могут быть настолько простыми или сложными, насколько это необходимо.
Для получения рекомендаций по созданию простых, готовых к использованию Rules см. раздел «Базовые правила безопасности» .