Firebase Security Rules позволяют контролировать доступ к хранимым данным. Гибкий синтаксис правил позволяет создавать правила, соответствующие чему угодно, от всех операций записи во всю базу данных до операций над конкретным документом.
В этом руководстве описаны некоторые из наиболее простых сценариев использования, которые могут вам понадобиться при настройке приложения и защите данных. Однако, прежде чем начать писать правила, вам, возможно, стоит узнать больше о языке, на котором они написаны, и об их поведении .
Чтобы получить доступ к своим правилам и обновить их, выполните действия, описанные в разделе «Управление и развертывание Firebase Security Rules .
Правила по умолчанию: Заблокированный режим
При создании экземпляра базы данных или хранилища в консоли Firebase вы выбираете, будут ли ваши Firebase Security Rules ограничивать доступ к вашим данным ( режим блокировки ) или разрешать доступ всем ( тестовый режим ). В Cloud Firestore и Realtime Database правила по умолчанию для режима блокировки запрещают доступ всем пользователям. В Cloud Storage доступ к хранилищам имеют только авторизованные пользователи.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
Realtime Database
{
"rules": {
".read": false,
".write": false
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if false;
}
}
}
правила среды развития
Во время работы над приложением вам может потребоваться относительно открытый или неограниченный доступ к данным. Просто не забудьте обновить Rules перед развертыванием приложения в продакшене. Также помните, что после развертывания приложение становится общедоступным — даже если вы его еще не запустили .
Помните, что Firebase предоставляет клиентам прямой доступ к вашим данным, и Firebase Security Rules — единственная защита, блокирующая доступ для злоумышленников. Определение правил отдельно от логики продукта имеет ряд преимуществ: клиенты не несут ответственности за обеспечение безопасности, ошибки в реализации не поставят под угрозу ваши данные, и, что наиболее важно, вы не полагаетесь на промежуточный сервер для защиты данных от внешнего мира.
Все авторизованные пользователи
Хотя мы не рекомендуем оставлять ваши данные доступными для всех авторизованных пользователей, может быть полезно установить доступ для всех прошедших аутентификацию пользователей на этапе разработки приложения.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /some_collection/{document} {
allow read, write: if request.auth != null;
}
}
}
Realtime Database
{
"rules": {
"some_path": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
}
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /some_folder/{fileName} {
allow read, write: if request.auth != null;
}
}
}
Правила, готовые к внедрению в производство
При подготовке к развертыванию приложения убедитесь, что ваши данные защищены и доступ пользователям предоставлен надлежащим образом. Используйте Authentication для настройки доступа на основе пользователей и прямое чтение из базы данных для настройки доступа на основе данных.
При структурировании данных рекомендуется создавать правила, поскольку способ их настройки влияет на ограничение доступа к данным по различным путям.
Доступ только для владельцев контента
Эти правила ограничивают доступ только авторизованному владельцу контента. Данные доступны для чтения и записи только одному пользователю, а путь к данным содержит идентификатор пользователя.
Когда это правило работает: Это правило хорошо работает, если данные хранятся изолированно по пользователям — если доступ к данным необходим только тому пользователю, который их создал.
Когда это правило не работает: Этот набор правил не работает, когда нескольким пользователям необходимо записывать или читать одни и те же данные — пользователи перезапишут данные или не смогут получить доступ к данным, которые они создали.
Чтобы настроить это правило: создайте правило, которое подтверждает, что пользователь, запрашивающий доступ к чтению или записи данных, является пользователем, которому эти данные принадлежат.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow only authenticated content owners access
match /some_collection/{userId}/{document} {
allow read, write: if request.auth != null && request.auth.uid == userId
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Allow only authenticated content owners access to their data
".read": "auth !== null && auth.uid === $uid",
".write": "auth !== null && auth.uid === $uid"
}
}
}
}
Cloud Storage
// Grants a user access to a node matching their user ID
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/file.txt"
match /user/{userId}/{fileName} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
Смешанный общественный и частный доступ
Это правило позволяет любому пользователю читать набор данных, но ограничивает возможность создания или изменения данных по указанному пути только авторизованным владельцем контента.
Когда это правило работает: Это правило хорошо подходит для приложений, которым требуются общедоступные элементы, но необходимо ограничить доступ к редактированию только для владельцев этих элементов. Например, для чат-приложений или блогов.
Когда это правило не работает: Как и правило, допускающее редактирование только владельцем контента, этот набор правил не работает, когда нескольким пользователям необходимо редактировать одни и те же данные. В конечном итоге пользователи перезапишут данные друг друга.
Для настройки этого правила: создайте правило, которое разрешает доступ на чтение для всех пользователей (или всех аутентифицированных пользователей) и подтверждает, что пользователь, записывающий данные, является владельцем.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow public read access, but only content owners can write
match /some_collection/{document} {
// Allow public reads
allow read: if true
// Allow creation if the current user owns the new document
allow create: if request.auth.uid == request.resource.data.author_uid;
// Allow updates by the owner, and prevent change of ownership
allow update: if request.auth.uid == request.resource.data.author_uid
&& request.auth.uid == resource.data.author_uid;
// Allow deletion if the current user owns the existing document
allow delete: if request.auth.uid == resource.data.author_uid;
}
}
}
Realtime Database
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"some_path": {
"$uid": {
".read": true,
// or ".read": "auth.uid !== null" for only authenticated users
".write": "auth.uid === $uid"
}
}
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/file.txt"
match /user/{userId}/{fileName} {
allow read;
allow write: if request.auth.uid == userId;
}
}
}
Доступ на основе атрибутов и на основе ролей.
Для работы этих правил необходимо определить и присвоить атрибуты пользователям в ваших данных. Firebase Security Rules проверяют запрос на соответствие данным из вашей базы данных или метаданным файла, чтобы подтвердить или отклонить доступ.
Когда работает это правило: Если вы назначаете пользователям роли, это правило позволяет ограничить доступ на основе ролей или определенных групп пользователей. Например, если вы храните оценки, вы можете назначить разные уровни доступа группе «студенты» (только чтение их содержимого), группе «учителя» (чтение и запись по их предмету) и группе «директора» (чтение всего содержимого).
Если это правило не работает: в Realtime Database и Cloud Storage ваши правила не могут использовать метод get() , который могут включать правила Cloud Firestore . Следовательно, вам необходимо структурировать метаданные вашей базы данных или файла таким образом, чтобы они отражали атрибуты, используемые в ваших правилах.
Чтобы настроить это правило: в Cloud Firestore добавьте в документы пользователей поле, которое вы можете прочитать, а затем структурируйте правило таким образом, чтобы оно считывало это поле и предоставляло доступ при определенных условиях. В Realtime Database создайте путь к данным, который определяет пользователей вашего приложения и предоставляет им роль в дочернем узле.
Вы также можете настроить пользовательские утверждения в Authentication , а затем получить эту информацию из переменной auth.token в любом из Firebase Security Rules .
Атрибуты и роли, определяемые данными
Эти правила работают только в Cloud Firestore и Realtime Database .
Cloud Firestore
Помните, что всякий раз, когда ваши правила включают операцию чтения, как в приведенных ниже правилах, с вас будет взиматься плата за операцию чтения в Cloud Firestore .
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, Check a boolean `admin` attribute
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"${subpath}": {
//
".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
".read": true
}
}
}
}
Пользовательские атрибуты и роли утверждений
Для реализации этих правил настройте пользовательские утверждения в Firebase Authentication , а затем используйте эти утверждения в своих правилах.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, check for an administrator claim
allow write: if request.auth.token.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if request.auth.token.reader == "true";
allow write: if request.auth.token.writer == "true";
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Create a custom claim for each role or group
// you want to use
".write": "auth.uid !== null && auth.token.writer === true",
".read": "auth.uid !== null && auth.token.reader === true"
}
}
}
}
Cloud Storage
service firebase.storage {
// Allow reads if the group ID in your token matches the file metadata's `owner` property
// Allow writes if the group ID is in the user's custom token
match /files/{groupId}/{fileName} {
allow read: if resource.metadata.owner == request.auth.token.groupId;
allow write: if request.auth.token.groupId == groupId;
}
}
Характеристики арендаторов
Для реализации этих правил настройте многопользовательский режим в Google Cloud Identity Platform (GCIP), а затем используйте имя арендатора в своих правилах. В следующих примерах разрешена запись данных пользователем из определенного арендатора, например, tenant2-m6tyz
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For tenant-based access control, check for a tenantID
allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
allow read: true;
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Only allow reads and writes if user belongs to a specific tenant
".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
".read": "auth.uid !== null
}
}
}
}
Cloud Storage
service firebase.storage {
// Only allow reads and writes if user belongs to a specific tenant
match /files/{tenantId}/{fileName} {
allow read: if request.auth != null;
allow write: if request.auth.token.firebase.tenant == tenantId;
}
}