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;
}
}
}
Смешанный публичный и частный доступ
Это правило позволяет любому пользователю читать набор данных, но ограничивает возможность создания или изменения данных по заданному пути только аутентифицированным владельцем контента.
Когда это правило работает: Это правило хорошо работает для приложений, которым требуются публично читаемые элементы, но необходимо ограничить доступ к редактированию для владельцев этих элементов. Например, приложение чата или блог.
Когда это правило не работает: Как и правило content-owner only, этот набор правил не работает, когда нескольким пользователям нужно редактировать одни и те же данные. Пользователи в конечном итоге перезапишут данные друг друга.
Чтобы настроить это правило: создайте правило, которое разрешает доступ на чтение всем пользователям (или всем аутентифицированным пользователям) и подтверждает, что пользователь, записывающий данные, является владельцем.
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), а затем используйте tenant в своих правилах. Следующие примеры разрешают запись от пользователя в определенном tenant, например 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;
}
}