Cloud Firestore Security Rules umożliwiają kontrolowanie dostępu do dokumentów i kolekcji w bazie danych. Elastyczna składnia reguł umożliwia tworzenie reguł, które pasują do wszystkiego, od wszystkich zapisów w całej bazie danych po operacje na konkretnym dokumencie.
W tym przewodniku opisujemy podstawową składnię i strukturę reguł bezpieczeństwa. Połącz tę składnię z warunkami reguł zabezpieczeń, aby utworzyć kompletne zestawy reguł.
Deklaracja dotycząca usługi i bazy danych
Cloud Firestore Security Rules zawsze zaczyna się od tego oświadczenia:
service cloud.firestore {
match /databases/{database}/documents {
// ...
}
}
Deklaracja service cloud.firestore
ogranicza zakres reguł do Cloud Firestore, zapobiegając konfliktom między Cloud Firestore Security Rules a regułami dotyczącymi innych usług, takich jak Cloud Storage.
Deklaracja match /databases/{database}/documents
określa, że reguły powinny pasować do dowolnej bazy danych Cloud Firestore w projekcie. Obecnie każdy projekt ma tylko jedną bazę danych o nazwie (default)
.
Podstawowe reguły odczytu i zapisu
Podstawowe reguły składają się z oświadczenia match
określającego ścieżkę dokumentu oraz wyrażenia allow
określającego, kiedy jest dozwolone odczytywanie określonych danych:
service cloud.firestore {
match /databases/{database}/documents {
// Match any document in the 'cities' collection
match /cities/{city} {
allow read: if <condition>;
allow write: if <condition>;
}
}
}
Wszystkie oświadczenia o dopasowaniu powinny wskazywać dokumenty, a nie kolekcje. Instrukcja dopasowania może wskazywać konkretny dokument, jak w przypadku match /cities/SF
, lub używać symboli wieloznacznych, aby wskazywać dowolny dokument na określonej ścieżce, jak w przypadku match /cities/{city}
.
W powyższym przykładzie instrukcja dopasowania używa składni zastępnika {city}
.
Oznacza to, że reguła dotyczy każdego dokumentu w kolekcji cities
, np. /cities/SF
lub /cities/NYC
. Gdy wyrażenia allow
w oświadczeniu o dopasowaniu zostaną ocenione, zmienna city
zostanie zastąpiona nazwą dokumentu miasta, np. SF
lub NYC
.
Operacje szczegółowe
W niektórych sytuacjach warto podzielić operacje read
i write
na bardziej szczegółowe operacje. Aplikacja może na przykład wymagać spełnienia różnych warunków podczas tworzenia dokumentu i jego usuwania. Możesz też zezwolić na odczyt pojedynczego dokumentu, ale odrzucić duże zapytania.
Regułę read
można podzielić na get
i list
, a regułę write
na create
, update
i delete
:
service cloud.firestore {
match /databases/{database}/documents {
// A read rule can be divided into get and list rules
match /cities/{city} {
// Applies to single document read requests
allow get: if <condition>;
// Applies to queries and collection read requests
allow list: if <condition>;
}
// A write rule can be divided into create, update, and delete rules
match /cities/{city} {
// Applies to writes to nonexistent documents
allow create: if <condition>;
// Applies to writes to existing documents
allow update: if <condition>;
// Applies to delete operations
allow delete: if <condition>;
}
}
}
Dane hierarchiczne
Dane w Cloud Firestore są porządkowane w kolekcji dokumentów, a każdy dokument może rozszerzać hierarchię za pomocą podkolekcji. Ważne jest, aby zrozumieć, jak reguły zabezpieczeń współdziałają z danymi hierarchicznymi.
Wyobraź sobie sytuację, w której każdy dokument w kolekcji cities
zawiera podkolekcję landmarks
. Reguły bezpieczeństwa mają zastosowanie tylko w przypadku dopasowanej ścieżki, więc mechanizmy kontroli dostępu zdefiniowane w zbiorze cities
nie mają zastosowania do podzbioru landmarks
. Zamiast tego napisz wyraźne reguły, które będą kontrolować dostęp do podzbiorów:
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city} {
allow read, write: if <condition>;
// Explicitly define rules for the 'landmarks' subcollection
match /landmarks/{landmark} {
allow read, write: if <condition>;
}
}
}
}
Gdy zagnieżdżasz instrukcje match
, ścieżka wewnętrznej instrukcji match
jest zawsze względna względem ścieżki zewnętrznej instrukcji match
. Dlatego te zestawy reguł są równoważne:
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city} {
match /landmarks/{landmark} {
allow read, write: if <condition>;
}
}
}
}
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city}/landmarks/{landmark} {
allow read, write: if <condition>;
}
}
}
Symbole wieloznaczne rekurencyjne
Jeśli chcesz, aby reguły były stosowane w dowolnie głębokiej hierarchii, użyj rekurencyjnej składni z symbolem wieloznacznym {name=**}
. Przykład:
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the cities collection as well as any document
// in a subcollection.
match /cities/{document=**} {
allow read, write: if <condition>;
}
}
}
Gdy używasz rekurencyjnej składni symboli wieloznacznych, zmienna symbolu wieloznacznego zawiera cały pasujący segment ścieżki, nawet jeśli dokument znajduje się w głęboko zagnieżdżonym podzbiorze. Na przykład reguły wymienione powyżej pasują do dokumentu znajdującego się w folderze /cities/SF/landmarks/coit_tower
, a wartość zmiennej document
to SF/landmarks/coit_tower
.
Pamiętaj jednak, że działanie symboli wieloznacznych rekurencyjnych zależy od wersji reguł.
Wersja 1
Reguły zabezpieczeń domyślnie używają wersji 1. W wersji 1 rekurencyjne symbole wieloznaczne pasują do co najmniej 1 elementu ścieżki. Nie pasują do pustej ścieżki, więc match /cities/{city}/{document=**}
pasuje do dokumentów w kolekcjach podrzędnych, ale nie w kolekcji cities
, podczas gdy match /cities/{document=**}
pasuje do dokumentów w kolekcji cities
i kolekcjach podrzędnych.
Rekurencyjne symbole wieloznaczne muszą znajdować się na końcu oświadczenia o dopasowaniu.
Wersja 2
W wersji 2 reguł zabezpieczeń symbole wieloznaczne w regułach rekurencyjnych pasują do 0 lub więcej elementów ścieżki. match/cities/{city}/{document=**}
pasuje do dokumentów w dowolnych podkolekcjach, a także do dokumentów w kolekcji cities
.
Musisz wyrazić zgodę na wersję 2, dodając rules_version = '2';
na początku swoich reguł zabezpieczeń:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the cities collection as well as any document
// in a subcollection.
match /cities/{city}/{document=**} {
allow read, write: if <condition>;
}
}
}
W przypadku każdego wyrażenia dopasowania możesz użyć maksymalnie 1 rekursywnego symbolu wieloznacznego, ale w wersji 2 możesz umieścić ten symbol w dowolnym miejscu wyrażenia dopasowania. Przykład:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the songs collection group
match /{path=**}/songs/{song} {
allow read, write: if <condition>;
}
}
}
Jeśli używasz zapytań dotyczących grup kolekcji, musisz używać wersji 2. Więcej informacji znajdziesz w sekcji Zabezpieczanie zapytań dotyczących grup kolekcji.
Zachodzące na siebie wyrażenia dopasowania
Dokument może pasować do więcej niż jednego oświadczenia match
. Jeśli wiele wyrażeń allow
pasuje do żądania, dostęp jest udzielany, jeśli co najmniej jedno z tych wyrażeń jest true
:
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the 'cities' collection.
match /cities/{city} {
allow read, write: if false;
}
// Matches any document in the 'cities' collection or subcollections.
match /cities/{document=**} {
allow read, write: if true;
}
}
}
W powyższym przykładzie wszystkie operacje odczytu i zapisu do kolekcji cities
będą dozwolone, ponieważ druga reguła jest zawsze true
, mimo że pierwsza reguła jest zawsze false
.
Ograniczenia reguł zabezpieczeń
Podczas pracy z regułami zabezpieczeń pamiętaj o tych ograniczeniach:
Limit | Szczegóły |
---|---|
Maksymalna liczba wywołań funkcji exists() , get() i getAfter() na żądanie |
Przekroczenie któregokolwiek z tych limitów powoduje błąd dotyczący braku uprawnień. Niektóre wywołania dostępu do dokumentu mogą być przechowywane w pamięci podręcznej, a wywołania z pamięci podręcznej nie wliczają się do limitów. |
Maksymalna głębokość zagnieżdżonego wyrażenia match |
10 |
Maksymalna długość ścieżki (w segmentach ścieżki) dozwolona w zbiorze ujęć match |
100 |
Maksymalna liczba zmiennych przechwytywania ścieżki dozwolonych w zestawie ujętych w nawiasy match instrukcji |
20 |
Maksymalna głębokość wywołania funkcji | 20 |
Maksymalna liczba argumentów funkcji | 7 |
Maksymalna liczba let powiązań zmiennych na funkcję |
10 |
Maksymalna liczba rekurencyjnych lub cyklicznych wywołań funkcji | 0 (niedozwolone) |
Maksymalna liczba wyrażeń ocenianych na żądanie | 1000 |
Maksymalny rozmiar zbioru reguł | Reguły muszą spełniać 2 limity rozmiaru:
|
Dalsze kroki
- Napisać warunki reguł zabezpieczeń niestandardowych.
- Przeczytaj dokumentację reguł zabezpieczeń.