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 ma zastosowanie do 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 stosować inne warunki tworzenia dokumentów niż ich 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ą uporzą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 zabezpieczeń 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 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 są wliczane do limitów. |
Maksymalna głębokość zagnięć 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 zagnięć match |
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ń.