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 opisano podstawową składnię i strukturę reguł zabezpieczeń. Połącz tę składnię z warunkami reguł zabezpieczeń, aby utworzyć aby utworzyć kompletne zestawy reguł.

Deklaracja dotycząca usługi i bazy danych

Cloud Firestore Security Rules zawsze zaczyna się od następującej deklaracji:

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 być zgodne z dowolną bazą danych Cloud Firestore w projekcie. Obecnie każdy projekt ma tylko jedną bazę danych o nazwie (default).

Podstawowe reguły odczytu/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 instrukcje dopasowania powinny wskazywać dokumenty, a nie kolekcje. Dopasowanie instrukcja może wskazywać konkretny dokument, na przykład match /cities/SF, lub użyć symboli wieloznacznych na dowolny dokument w określonej ścieżce, np. 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 wszystkich dokumentów w kolekcji cities, na przykład /cities/SF lub /cities/NYC. Gdy wyrażenia allow w instrukcji dopasowania to analizowana, zmienna city przyjmie nazwę dokumentu miasta, na przykład SF lub NYC.

Operacje szczegółowe

W niektórych sytuacjach warto podzielić operacje readwrite na bardziej szczegółowe operacje. Aplikacja może na przykład wymuszać w aplikacji różne warunków tworzenia dokumentu niż przy jego usunięciu. 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 usłudze Cloud Firestore są porządkowane w kolekcje dokumentów, z których każda dokument może rozszerzyć hierarchię za pomocą kolekcji podrzędnych. Ważne jest, zrozumieć, jak reguły zabezpieczeń współdziałają z danymi hierarchicznymi.

Weźmy pod uwagę sytuację, w której każdy dokument w kolekcji cities zawiera element landmarks kolekcja podrzędna. Reguły zabezpieczeń są stosowane tylko w przypadku dopasowanej ścieżki, więc kontrole dostępu zdefiniowane w kolekcji cities nie mają zastosowania do landmarks kolekcja podrzędna. 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. Te zestawy reguł są więc 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 do dowolnie głębszej hierarchii, użyj funkcji rekurencyjna składnia 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>;
    }
  }
}

Jeśli używasz składni rekurencyjnego symbolu wieloznacznego, zmienna z symbolem wieloznacznym będzie zawierać parametr całego pasującego segmentu ścieżki, nawet jeśli dokument znajduje się w głęboko zagnieżdżonym podkolekcja. Na przykład wymienione powyżej reguły będą pasować dokumentu znajdującego się pod adresem /cities/SF/landmarks/coit_tower, a wartość zmienna document będzie miała wartość SF/landmarks/coit_tower.

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

Wersja 1

Reguły zabezpieczeń używają domyślnie 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 podkolekcjach, ale nie w kolekcji cities, podczas gdy match /cities/{document=**} pasuje do dokumentów w kolekcji cities i podkolekcjach.

Rekurencyjne symbole wieloznaczne muszą znajdować się na końcu instrukcji dopasowania.

Wersja 2

W wersji 2 reguł zabezpieczeń rekurencyjne symbole wieloznaczne pasują do 0 lub większej liczby ścieżek elementy(ów). 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>;
    }
  }
}

Możesz użyć maksymalnie 1 rekurencyjnego symbolu wieloznacznego na wyrażenie dopasowania, ale w wersji 2, możesz umieścić ten symbol wieloznaczny w dowolnym miejscu w instrukcji 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.

Nakładające się instrukcje dopasowania

Dokument może pasować do więcej niż jednego oświadczenia match. W jeśli do żądania pasuje wiele 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 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ń exists(), get() i getAfter() na żądanie
  • 10 w przypadku żądań pojedynczych dokumentów i zapytań.
  • 20 dla operacji odczytu wielu dokumentów, transakcji i zapisów zbiorczych. Poprzedni limit 10 operacji obowiązuje również w przypadku każdej operacji.

    Załóżmy na przykład, że tworzysz zbiorczy żądanie zapisu z 3 operacjami zapisu i że Twoje reguły zabezpieczeń używają 2 wywołań dostępu do dokumentu do sprawdzania każdego zapisu. W tym przypadku każdy zapis używa 2 z 10 wywołań dostępu i zbiorcze żądanie zapisu używa 6 z 20 wywołań dostępu.

Przekroczenie dowolnego z limitów skutkuje błędem braku uprawnień.

Niektóre wywołania dostępu do dokumentów mogą być przechowywane w pamięci podręcznej, i połączenia z pamięci podręcznej nie wliczają się do tych limitów.

Maksymalna głębokość zagnieżdżonej instrukcji 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 powiązań zmiennych na funkcję (let) 10
Maksymalna liczba rekurencyjnych lub cyklicznych wywołań funkcji 0 &lpar;niedozwolone&rpar;
Maksymalna liczba wyrażeń ocenianych na żądanie 1000
Maksymalny rozmiar zbioru reguł Zestawy reguł muszą przestrzegać 2 limitów rozmiarów:
  • limit 256 KB na rozmiar źródła tekstowego reguł opublikowanego z poziomu konsoli Firebase lub za pomocą interfejsu wiersza poleceń za pomocą polecenia firebase deploy.
  • limit 250 KB na rozmiar skompilowanego zbioru reguł, który powstaje, gdy Firebase przetworzy źródło i uaktywni je na zapleczu;

Dalsze kroki