Firebase Security Rules для Cloud Storage позволяют контролировать доступ к объектам, хранящимся в контейнерах Cloud Storage . Гибкий синтаксис правил позволяет создавать правила для управления любыми операциями: от всех записей в контейнер Cloud Storage до операций с конкретным файлом.
В этом руководстве описывается базовый синтаксис и структура Cloud Storage Security Rules для создания полных наборов правил.
Декларация сервиса и базы данных
Firebase Security Rules для Cloud Storage всегда начинаются со следующего объявления:
service firebase.storage {
// ...
}
Объявление service firebase.storage
распространяет действие правил на Cloud Storage , предотвращая конфликты между Cloud Storage Security Rules и правилами для других продуктов, таких как Cloud Firestore .
Основные правила чтения/записи
Базовые правила состоят из оператора match
, идентифицирующего контейнеры Cloud Storage , оператора сопоставления, указывающего имя файла, и allow
выражения, подробно описывающего, когда разрешено чтение указанных данных. allow
выражения определяют используемые методы доступа (например, чтение, запись) и условия, при которых доступ либо разрешен, либо запрещен.
В вашем наборе правил по умолчанию первый оператор match
использует подстановочное выражение {bucket}
чтобы указать, что правила применяются ко всем контейнерам в вашем проекте. Мы подробнее обсудим идею подстановочных символов в следующем разделе.
service firebase.storage {
// The {bucket} wildcard indicates we match files in all Cloud Storage buckets
match /b/{bucket}/o {
// Match filename
match /filename {
allow read: if <condition>;
allow write: if <condition>;
}
}
}
Все операторы сопоставления указывают на файлы. Оператор сопоставления может указывать на конкретный файл, например, match /images/profilePhoto.png
.
Подстановочные знаки
Помимо указания на один файл, Rules могут использовать подстановочные знаки для указания на любой файл с заданным строковым префиксом в имени, включая косые черты, как в match /images/{imageId}
.
В приведенном выше примере оператор match использует подстановочный знак {imageId}
. Это означает, что правило применяется к любому файлу, имя которого начинается с /images/
, например, /images/profilePhoto.png
или /images/croppedProfilePhoto.png
. При вычислении выражений allow
в операторе match переменная imageId
преобразуется в имя файла изображения, например, profilePhoto.png
или croppedProfilePhoto.png
.
Из match
можно сослаться на подстановочную переменную, чтобы предоставить авторизацию имени файла или пути:
// Another way to restrict the name of a file
match /images/{imageId} {
allow read: if imageId == "profilePhoto.png";
}
Иерархические данные
Как мы уже говорили, внутри контейнера Cloud Storage нет иерархической структуры. Но, используя соглашение об именовании файлов, часто включающее косые черты, мы можем имитировать структуру, похожую на вложенную последовательность каталогов и подкаталогов. Важно понимать, как Firebase Security Rules взаимодействуют с этими именами файлов.
Рассмотрим набор файлов, имена которых начинаются с корня /images/
. Firebase Security Rules применяются только к соответствующему имени файла, поэтому контроль доступа, заданный для корня /images/
не применяется к корневому узлу /mp3s/
. Вместо этого напишите явные правила, соответствующие различным шаблонам имён файлов:
service firebase.storage {
match /b/{bucket}/o {
match /images/{imageId} {
allow read, write: if <condition>;
}
// Explicitly define rules for the 'mp3s' pattern
match /mp3s/{mp3Id} {
allow read, write: if <condition>;
}
}
}
При вложенных операторах match
путь внутреннего оператора match
всегда добавляется к пути внешнего оператора match
. Таким образом, следующие два набора правил эквивалентны:
service firebase.storage {
match /b/{bucket}/o {
match /images {
// Exact match for "images/profilePhoto.png"
match /profilePhoto.png {
allow write: if <condition>;
}
}
}
}
service firebase.storage {
match /b/{bucket}/o {
// Exact match for "images/profilePhoto.png"
match /images/profilePhoto.png {
allow write: if <condition>;
}
}
}
Рекурсивные подстановочные знаки
Помимо подстановочных знаков, которые сопоставляются и возвращают строки в конце имени файла, можно объявить многосегментный подстановочный знак для более сложного сопоставления, добавив =**
к имени подстановочного знака, например {path=**}
:
// Partial match for files that start with "images"
match /images {
// Exact match for "images/**"
// e.g. images/users/user:12345/profilePhoto.png is matched
// images/profilePhoto.png is also matched!
match /{allImages=**} {
// This rule matches one or more path segments (**)
// allImages is a path that contains all segments matched
allow read: if <other_condition>;
}
}
Если файлу соответствует несколько правил, результат вычисляется по OR
для всех правил. То есть, если хотя бы одно правило, которому соответствует файл, оценивается как true
, результат будет true
.
В приведенных выше правилах файл «images/profilePhoto.png» может быть прочитан, если либо condition
, либо other_condition
оцениваются как true, тогда как файл «images/users/user:12345/profilePhoto.png» подчиняется только результату other_condition
.
Cloud Storage Security Rules не каскадируются, и правила оцениваются только в том случае, если путь запроса совпадает с путем, указанным в правилах.
Версия 1
Firebase Security Rules по умолчанию используют версию 1. В версии 1 рекурсивные подстановочные знаки соответствуют одному или нескольким элементам имени файла, а не нулю или более. Таким образом, match /images/{filenamePrefixWildcard}/{imageFilename=**}
соответствует имени файла типа /images/profilePics/profile.png, но не /images/badge.png. Вместо этого используйте /images/{imagePrefixorFilename=**}
.
Рекурсивные подстановочные знаки должны располагаться в конце оператора сопоставления.
Мы рекомендуем использовать версию 2 из-за ее более мощных функций.
Версия 2
В версии 2 Firebase Security Rules рекурсивные подстановочные знаки соответствуют нулю или более элементам пути. Таким образом, /images/{filenamePrefixWildcard}/{imageFilename=**}
соответствует именам файлов /images/profilePics/profile.png и /images/badge.png.
Вам необходимо включить версию 2, добавив rules_version = '2';
в начало правил безопасности:
rules_version = '2';
service cloud.storage {
match /b/{bucket}/o {
...
}
}
В каждом операторе сопоставления может быть не более одного рекурсивного подстановочного знака, но в версии 2 этот подстановочный знак можно разместить в любом месте оператора сопоставления. Например:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// Matches any file in a songs "subdirectory" under the
// top level of your Cloud Storage bucket.
match /{prefixSegment=**}/songs/{mp3filenames} {
allow read, write: if <condition>;
}
}
}
Гранулированные операции
В некоторых ситуациях полезно разбить read
и write
на более мелкие операции. Например, ваше приложение может требовать применения разных условий при создании и удалении файлов.
Операцию read
можно разбить на get
и list
.
Правило write
можно разбить на create
, update
и delete
:
service firebase.storage { match /b/{bucket}/o { // A read rule can be divided into read and list rules match /images/{imageId} { // Applies to single file read requests allow get: if <condition>; // Applies to list and listAll requests (Rules Version 2) allow list: if <condition>; // A write rule can be divided into create, update, and delete rules match /images/{imageId} { // Applies to writes to file contents allow create: if <condition>; // Applies to updates to (pre-existing) file metadata allow update: if <condition>; // Applies to delete operations allow delete: if <condition>; } } } }
Перекрывающиеся заявления о совпадении
Имя файла может соответствовать нескольким операторам match
. Если запросу соответствует несколько выражений allow
, доступ разрешается, если true
хотя бы одно из условий:
service firebase.storage {
match b/{bucket}/o {
// Matches file names directly inside of '/images/'.
match /images/{imageId} {
allow read, write: if false;
}
// Matches file names anywhere under `/images/`
match /images/{imageId=**} {
allow read, write: if true;
}
}
}
В приведенном выше примере разрешены все операции чтения и записи в файлы, имена которых начинаются с /images/
поскольку второе правило всегда true
, даже если первое правило false
.
Правила не являются фильтрами
Защитив свои данные и начав выполнять файловые операции, помните, что правила безопасности не являются фильтрами. Вы не можете выполнять операции с набором файлов, соответствующим шаблону имени файла, и ожидать, что Cloud Storage будет получать доступ только к тем файлам, на доступ к которым у текущего клиента есть разрешение.
Например, возьмем следующее правило безопасности:
service firebase.storage {
match /b/{bucket}/o {
// Allow the client to read files with contentType 'image/png'
match /aFileNamePrefix/{aFileName} {
allow read: if resource.contentType == 'image/png';
}
}
}
Отклонено : это правило отклоняет следующий запрос, поскольку набор результатов может включать файлы, в которых contentType
не является image/png
:
Интернет
filesRef = storage.ref().child("aFilenamePrefix"); filesRef.listAll() .then(function(result) { console.log("Success: ", result.items); }) });
Cloud Storage Security Rules оценивают каждый запрос с учетом его потенциального результата и отклоняют запрос, если он может вернуть файл, на чтение которого у клиента нет прав. Запросы на доступ должны соответствовать ограничениям, установленным вашими правилами.
Следующие шаги
Вы можете углубить свое понимание Firebase Security Rules для Cloud Storage :
Изучите следующую важную концепцию языка правил — динамические условия , которые позволяют вашим правилам проверять авторизацию пользователя, сравнивать существующие и входящие данные, проверять входящие данные и многое другое.
Ознакомьтесь с типичными вариантами использования безопасности и определениями Firebase Security Rules , которые их касаются .
Вы можете изучить примеры использования Firebase Security Rules , специфичные для Cloud Storage :