Firebase Security Rules позволяют контролировать доступ к хранимым данным. Гибкий синтаксис правил позволяет создавать правила, которые будут применяться к чему угодно: от всех записей во всей базе данных до операций с конкретным документом.
В этом руководстве описаны некоторые из наиболее простых вариантов использования, которые вы можете использовать при настройке приложения и защите данных. Однако, прежде чем приступить к написанию правил, вам, возможно, стоит узнать больше о языке, на котором они написаны, и их поведении .
Чтобы получить доступ к правилам и обновить их, следуйте инструкциям в разделе Управление и развертывание Firebase Security Rules .
Правила по умолчанию: Заблокированный режим
При создании экземпляра базы данных или хранилища в консоли Firebase вы выбираете, будут ли Firebase Security Rules ограничивать доступ к вашим данным ( режим Locked ) или разрешать его любому пользователю ( тестовый режим ). В Cloud Firestore и Realtime Database правила по умолчанию для режима Locked запрещают доступ всем пользователям. В 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;
}
}