Tworzenie struktury reguł zabezpieczeń Cloud Firestore

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 zaczynaj od tego oświadczenia:

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 innych usług, takich jak Cloud Storage.

Deklaracja match /databases/{database}/documents oznacza, że reguły powinny pasować do dowolnej bazy danych Cloud Firestore w projekcie. Projekt może zawierać do 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 w każdej z nich oddzielnie. Szczegółowe instrukcje wdrażania aktualizacji znajdziesz w artykule Wdrażanie aktualizacji.

Podstawowe reguły odczytu i zapisu

Reguły podstawowe składają się z instrukcji match określającej ścieżkę dokumentu i wyrażenia allow, które szczegółowo opisuje, 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 oświadczenia o dopasowaniu powinny wskazywać dokumenty, a nie kolekcje. Instrukcja dopasowania 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 przykładzie powyżej instrukcja dopasowania używa składni symbolu wieloznacznego {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 instrukcji dopasowania zostaną ocenione, zmienna city zostanie przekształcona w nazwę dokumentu miasta, np. SF lub NYC.

Szczegółowe operacje

W niektórych sytuacjach warto podzielić operacje readwrite na bardziej szczegółowe. Na przykład aplikacja może wymagać spełnienia innych warunków w przypadku tworzenia dokumentu niż w przypadku jego usuwania. Możesz też zezwolić na odczytywanie pojedynczych dokumentów, ale odrzucać duże zapytania.

Regułę read można podzielić na getlist, a regułę write – na create, updatedelete:

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ą podkolekcji. Ważne jest, aby zrozumieć, jak reguły zabezpieczeń działają w przypadku danych hierarchicznych.

Rozważ sytuację, w której każdy dokument w kolekcji cities zawiera podkolekcję landmarks. Reguły zabezpieczeń mają zastosowanie tylko do pasującej ścieżki, więc mechanizmy kontroli dostępu zdefiniowane w kolekcji cities nie mają zastosowania do podkolekcji landmarks. Zamiast tego napisz jawne reguły, aby 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>;
        }
    }
  }
}

W przypadku zagnieżdżania instrukcji match ścieżka wewnętrznej instrukcji match jest zawsze względna w stosunku do ścieżki zewnętrznej instrukcji match. W związku z tym poniższe 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>;
    }
  }
}

Rekurencyjne symbole wieloznaczne

Jeśli chcesz, aby reguły miały zastosowanie do dowolnie głębokiej hierarchii, użyj rekursywnej składni symbolu wieloznacznego – {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>;
    }
  }
}

W przypadku użycia rekursywnej składni symbolu wieloznacznego 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 podkolekcji. Na przykład reguły wymienione powyżej będą pasować do dokumentu znajdującego się w /cities/SF/landmarks/coit_tower, a wartość zmiennej document będzie wynosić SF/landmarks/coit_tower.

Pamiętaj jednak, że działanie rekurencyjnych symboli wieloznacznych zależy od wersji reguł.

Wersja 1

Reguły zabezpieczeń domyślnie korzystają z wersji 1. W wersji 1 rekursywne 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, natomiast match /cities/{document=**} pasuje do dokumentów w kolekcji cities i kolekcjach podrzędnych.

Rekursywne symbole wieloznaczne muszą znajdować się na końcu oświadczenia o dopasowaniu.

Wersja 2

W wersji 2 reguł zabezpieczeń rekursywne symbole wieloznaczne pasują do 0 lub większej liczby elementów ścieżki. Symbol match/cities/{city}/{document=**} pasuje do dokumentów w dowolnych podzbiorach, a także do dokumentów w kolekcji cities.

Aby włączyć wersję 2, musisz dodać 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 każdym wyrażeniu dopasowania możesz użyć maksymalnie jednego rekurencyjnego symbolu wieloznacznego, ale w wersji 2 możesz go umieścić 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 artykule Zabezpieczanie zapytań dotyczących grup kolekcji.

Nakładające się instrukcje dopasowania

Dokument może pasować do więcej niż 1 match. Jeśli z żądaniem 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 operacje odczytu i zapisu w kolekcji cities będą dozwolone, ponieważ druga reguła zawsze ma wartość true, mimo że pierwsza reguła zawsze ma wartość false.

Limity reguł zabezpieczeń

Podczas pracy z regułami zabezpieczeń pamiętaj o tych limitach:

Limit Szczegóły
Maksymalna liczba wywołań exists(), get()getAfter() na żądanie
  • 10 w przypadku żądań dotyczących pojedynczego dokumentu i zapytań.
  • 20 w przypadku odczytów wielu dokumentów, transakcji i zapisów zbiorczych. Poprzedni limit wynoszący 10 dotyczy też każdej operacji.

    Załóżmy na przykład, że tworzysz żądanie zapisu zbiorczego z 3 operacjami zapisu, a Twoje reguły zabezpieczeń używają 2 wywołań dostępu do dokumentu, aby zweryfikować każdy zapis. W takim przypadku każdy zapis wykorzystuje 2 z 10 wywołań dostępu, a żądanie zapisu zbiorczego wykorzystuje 6 z 20 wywołań dostępu.

Przekroczenie któregokolwiek z tych limitów spowoduje wyświetlenie błędu dotyczącego braku uprawnień.

Niektóre wywołania dostępu do dokumentów mogą być buforowane, a buforowane wywołania 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 instrukcji match 100
Maksymalna liczba zmiennych przechwytywania ścieżki dozwolonych w zagnieżdżonych instrukcjach match 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 rekurencyjnych lub cyklicznych wywołań funkcji 0 (niedozwolone)
Maksymalna liczba wyrażeń ocenianych w ramach jednego żądania 1000
Maksymalny rozmiar zestawu reguł Zbiory reguł muszą spełniać 2 limity rozmiaru:
  • limit 256 KB na rozmiar źródła tekstu zestawu reguł opublikowanego w konsoli Firebase lub w interfejsie wiersza poleceń za pomocą firebase deploy.
  • limit 250 KB na rozmiar skompilowanego zbioru reguł, który powstaje, gdy Firebase przetwarza źródło i aktywuje je na backendzie;

Dalsze kroki