Cloud Firestore Security Rules umożliwiają kontrolowanie dostępu do dokumentów i kolekcji w bazie danych. Elastyczna składnia reguł pozwala tworzyć reguły, 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ł zabezpieczeń. Połącz tę składnię z warunkami reguł zabezpieczeń, aby utworzyć kompletne zestawy reguł.
Deklaracja usługi i bazy danych
Cloud Firestore Security Rules zawsze zaczynają się od tej deklaracji:
service cloud.firestore {
// The {database} wildcard allows the rules to reference any database,
// but these rules are only active on databases where they are explicitly deployed.
match /databases/{database}/documents {
// ...
}
}Deklaracja service cloud.firestore ogranicza zakres reguł do
Cloud Firestore, co zapobiega 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. Projekt może zawierać maksymalnie 100 baz danych, ale tylko pierwsza utworzona baza danych jest oznaczona jako domyślna.
Cloud Firestore Security Rules są stosowane oddzielnie do każdej nazwanej bazy danych w projekcie. Oznacza to, że jeśli utworzysz kilka baz danych, musisz zarządzać regułami i wdrażać je oddzielnie dla każdej z nich. Szczegółowe instrukcje wdrażania aktualizacji znajdziesz w artykule Wdrażanie aktualizacji.
Podstawowe reguły odczytu i zapisu
Podstawowe reguły składają się z instrukcji match określającej ścieżkę dokumentu oraz wyrażenia allow określającego, kiedy dozwolony jest odczyt 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 instrukcje match powinny wskazywać dokumenty, a nie kolekcje. Instrukcja match może wskazywać konkretny dokument, np. match /cities/SF, lub używać symboli wieloznacznych, aby wskazywać dowolny dokument w określonej ścieżce, np. match /cities/{city}.
W powyższym przykładzie instrukcja match używa składni symbolu wieloznacznego {city}.
Oznacza to, że reguła ma zastosowanie do dowolnego dokumentu w kolekcji cities, np.
/cities/SF lub /cities/NYC. Gdy wyrażenia allow w instrukcji match są oceniane, zmienna city jest rozwiązywana na 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. Na przykład aplikacja może wymagać stosowania innych warunków podczas tworzenia dokumentu niż podczas jego usuwania. Możesz też zezwolić na odczyt pojedynczych dokumentów, ale zabronić wykonywania dużych zapytań.
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 kolekcje dokumentów, a każdy dokument może rozszerzać hierarchię za pomocą kolekcji podrzędnych. Ważne jest, aby zrozumieć, jak reguły zabezpieczeń współdziałają z danymi hierarchicznymi.
Załóżmy, że każdy dokument w kolekcji cities zawiera kolekcję podrzędną landmarks. Reguły zabezpieczeń mają zastosowanie tylko do pasującej ścieżki, więc kontrola dostępu zdefiniowana w kolekcji cities nie ma zastosowania do kolekcji podrzędnej landmarks. Zamiast tego napisz wyraźne reguły, aby kontrolować dostęp do kolekcji podrzędnych:
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>; } } } }
Podczas zagnieżdżania instrukcji match ścieżka wewnętrznej instrukcji match jest zawsze względna w stosunku do ś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 miały zastosowanie do dowolnie głębokiej hierarchii, użyj składni symbolu wieloznacznego rekurencyjnego {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 składni symbolu wieloznacznego rekurencyjnego, zmienna symbolu wieloznacznego będzie zawierać cały pasujący segment ścieżki, nawet jeśli dokument znajduje się w głęboko zagnieżdżonej kolekcji podrzędnej. Na przykład reguły wymienione powyżej będą pasować do
dokumentu znajdującego się w lokalizacji /cities/SF/landmarks/coit_tower, a wartość
zmiennej document będzie równa 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 symbole wieloznaczne rekurencyjne 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, natomiast match /cities/{document=**} pasuje
zarówno do dokumentów w kolekcji cities, jak i w kolekcjach podrzędnych.
Symbole wieloznaczne rekurencyjne muszą znajdować się na końcu instrukcji match.
Wersja 2
W wersji 2 reguł zabezpieczeń symbole wieloznaczne rekurencyjne pasują do zera lub większej liczby elementów ścieżki. match/cities/{city}/{document=**} pasuje do dokumentów w dowolnych
kolekcjach podrzędnych oraz do dokumentów w kolekcji cities.
Aby włączyć wersję 2, dodaj rules_version = '2'; u góry
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 każdej instrukcji match możesz mieć co najwyżej 1 symbol wieloznaczny rekurencyjny, ale w wersji 2 możesz umieścić go w dowolnym miejscu instrukcji match. 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ń do grup kolekcji, musisz użyć wersji 2. Więcej informacji znajdziesz w artykule Zabezpieczanie zapytań do grup kolekcji.
Nakładające się instrukcje match
Dokument może pasować do więcej niż 1 instrukcji match. Jeśli do żądania pasuje kilka wyrażeń allow, dostęp jest dozwolony, jeśli którykolwiek z warunków 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 odczyty i zapisy w kolekcji cities będą dozwolone, ponieważ druga reguła jest zawsze true, nawet jeśli pierwsza reguła jest zawsze false.
Limity reguł zabezpieczeń
Podczas pracy z regułami zabezpieczeń pamiętaj o tych limitach:
| Limit | Szczegóły |
|---|---|
Maksymalna liczba wywołań exists(), get() i getAfter() na żądanie |
Przekroczenie któregokolwiek z tych limitów powoduje błąd odmowy uprawnień. Niektóre wywołania dostępu do dokumentu mogą być buforowane, a wywołania buforowane nie są wliczane do limitów. |
Maksymalna głębokość zagnieżdżenia instrukcji match |
10 |
Maksymalna długość ścieżki w segmentach ścieżki dozwolona w zbiorze zagnieżdżonych
match instrukcji |
100 |
Maksymalna liczba zmiennych przechwytywania ścieżki dozwolona w zbiorze zagnieżdżonych
match instrukcji |
20 |
| Maksymalna głębokość wywołania funkcji | 20 |
| Maksymalna liczba argumentów funkcji | 7 |
Maksymalna liczba powiązań zmiennych let na funkcję |
10 |
| Maksymalna liczba wywołań funkcji rekurencyjnych lub cyklicznych | 0 (niedozwolone) |
| Maksymalna liczba wyrażeń ocenianych na żądanie | 1000 |
| Maksymalny rozmiar zestawu reguł | Zestawy reguł muszą spełniać 2 limity rozmiaru:
|
Dalsze kroki
- Napisz własne warunki reguł zabezpieczeń.
- Przeczytaj dokumentację reguł zabezpieczeń.