Catch up on highlights from Firebase at Google I/O 2023. Learn more

Strukturyzacja reguł bezpieczeństwa Cloud Firestore

Reguły bezpieczeństwa Cloud Firestore pozwalają kontrolować dostęp do dokumentów i kolekcji w Twojej bazie danych. Elastyczna składnia reguł pozwala tworzyć reguły pasujące do wszystkiego, od wszystkich zapisów, przez całą bazę danych, po operacje na określonym dokumencie.

W tym przewodniku opisano podstawową składnię i strukturę reguł bezpieczeństwa. Połącz tę składnię z warunkami reguł bezpieczeństwa, aby utworzyć kompletne zestawy reguł.

Deklaracja usługi i bazy danych

Reguły bezpieczeństwa Cloud Firestore zawsze zaczynają się od następującej deklaracji:

service cloud.firestore {
  match /databases/{database}/documents {
    // ...
  }
}

Deklaracja service cloud.firestore obejmuje reguły Cloud Firestore, zapobiegając konfliktom między Regułami bezpieczeństwa Cloud Firestore a regułami dla innych produktów, 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 zasady odczytu/zapisu

Podstawowe reguły składają się z instrukcji match określającej ścieżkę do dokumentu oraz wyrażenia allow , które szczegółowo określa, kiedy odczyt określonych danych jest dozwolony:

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. Instrukcja match może wskazywać na konkretny dokument, jak w match /cities/SF lub użyć symboli wieloznacznych, aby wskazać dowolny dokument w określonej ścieżce, jak w match /cities/{city} .

W powyższym przykładzie instrukcja dopasowania używa symboli wieloznacznych {city} . Oznacza to, że reguła ma zastosowanie do dowolnego dokumentu w kolekcji cities , takiego jak /cities/SF lub /cities/NYC . Po ocenie wyrażeń allow w instrukcji dopasowania zmienna city zostanie rozpoznana jako nazwa dokumentu miasta, na przykład SF lub NYC .

Operacje szczegółowe

W niektórych sytuacjach warto podzielić read i write na bardziej szczegółowe operacje. Na przykład Twoja aplikacja może chcieć wymusić inne warunki przy tworzeniu dokumentu niż przy jego usuwaniu. Lub możesz zezwolić na odczyt pojedynczego dokumentu, ale odmówić dużych zapytań.

Regułę read można podzielić na get i list , podczas gdy regułę write można podzielić 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ą zorganizowane w kolekcje dokumentów, a każdy dokument może rozszerzać hierarchię poprzez podkolekcje. Ważne jest, aby zrozumieć, w jaki sposób reguły bezpieczeństwa wchodzą w interakcję z danymi hierarchicznymi.

Rozważmy sytuację, w której każdy dokument w zbiorze cities zawiera podzbiór landmarks . Reguły bezpieczeństwa mają zastosowanie tylko do dopasowanej ścieżki, więc kontrola dostępu zdefiniowana w zbiorze cities nie ma zastosowania do podzbioru landmarks . Zamiast tego napisz wyraźne reguły kontrolujące dostęp do podkolekcji:

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 względem ścieżki zewnętrznej instrukcji match . Następujące zestawy reguł są zatem 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 rekurencyjnej składni symboli wieloznacznych, {name=**} . Na 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 rekurencyjnej składni symboli wieloznacznych zmienna wieloznaczna 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 pasowałyby do dokumentu znajdującego się w /cities/SF/landmarks/coit_tower , a wartość zmiennej document to SF/landmarks/coit_tower .

Należy jednak pamiętać, że zachowanie rekurencyjnych symboli wieloznacznych zależy od wersji reguł.

Wersja 1

Reguły bezpieczeństwa domyślnie używają wersji 1. W wersji 1 rekurencyjne symbole wieloznaczne pasują do jednego lub większej liczby elementów ścieżki. Nie pasują do pustej ścieżki, więc match /cities/{city}/{document=**} dopasowuje dokumenty w podkolekcjach, ale nie w kolekcji cities , natomiast match /cities/{document=**} dopasowuje oba dokumenty w kolekcja cities i podkolekcje.

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

Wersja 2

W wersji 2 reguł bezpieczeństwa rekurencyjne symbole wieloznaczne pasują do zera lub większej liczby elementów ścieżki. match/cities/{city}/{document=**} dopasowuje dokumenty w dowolnych podkolekcjach, jak również dokumenty w kolekcji cities .

Musisz wyrazić zgodę na wersję 2, dodając rules_version = '2'; u góry reguł bezpieczeństwa:

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 mieć co najwyżej jeden rekurencyjny symbol wieloznaczny na instrukcję dopasowania, ale w wersji 2 możesz umieścić ten symbol wieloznaczny w dowolnym miejscu instrukcji dopasowania. Na 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>;
    }
  }
}

W przypadku korzystania z zapytań dotyczących grup kolekcji należy używać wersji 2, patrz zabezpieczanie zapytań dotyczących grup kolekcji .

Nakładające się instrukcje dopasowania

Dokument może pasować do więcej niż jednej instrukcji match . W przypadku, gdy wiele wyrażeń allow pasuje do żądania, 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 do kolekcji cities będą dozwolone, ponieważ druga reguła jest zawsze true , mimo że pierwsza reguła jest zawsze false .

Limity reguł bezpieczeństwa

Podczas pracy z regułami bezpieczeństwa należy zwrócić uwagę na następujące ograniczenia:

Limit Detale
Maksymalna liczba exists() , get() i getAfter() na żądanie
  • 10 dla żądań pojedynczych dokumentów i zapytań.
  • 20 dla wielodokumentowych odczytów, transakcji i zapisów wsadowych. Poprzedni limit 10 dotyczy również każdej operacji.

    Na przykład wyobraź sobie, że tworzysz żądanie zapisu wsadowego z 3 operacjami zapisu i że twoje reguły bezpieczeństwa używają 2 wywołań dostępu do dokumentów do sprawdzania poprawności każdego zapisu. W takim przypadku każdy zapis wykorzystuje 2 z 10 wywołań dostępu, a żądanie zapisu wsadowego wykorzystuje 6 z 20 wywołań dostępu.

Przekroczenie któregokolwiek z limitów skutkuje błędem odmowy uprawnień.

Niektóre wywołania dostępu do dokumentów mogą być buforowane, a wywołania buforowane nie wliczają się do limitów.

Maksymalna głębokość zagnieżdżonej instrukcji match 10
Maksymalna długość ścieżki, w segmentach ścieżki, dozwolona w zestawie zagnieżdżonych instrukcji match 100
Maksymalna liczba zmiennych przechwytywania ścieżki dozwolona w zestawie zagnieżdżonych instrukcji 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 na żądanie 1000
Maksymalny rozmiar zestawu reguł Zestawy reguł muszą przestrzegać dwóch ograniczeń rozmiaru:
  • limit 256 KB rozmiaru źródła tekstowego zestawu reguł publikowanego z konsoli Firebase lub z interfejsu wiersza polecenia za pomocą firebase deploy .
  • limit 250 KB rozmiaru skompilowanego zestawu reguł, który pojawia się, gdy Firebase przetwarza źródło i uaktywnia je na zapleczu.

Następne kroki