Korzystanie z warunków w regułach zabezpieczeń Cloud Storage Firebase

Ten przewodnik opiera się na poznawaniu podstawowej składni przewodnika w języku Firebase Security Rules. aby pokazać, jak dodać warunki do: Firebase Security Rules dla: Cloud Storage.

Podstawowym elementem Cloud Storage Security Rules jest warunek. O Warunek jest wyrażeniem logicznym określającym, czy określona operacja powinno być dozwolone lub zabronione. W przypadku prostych reguł stosowanie literalnych wartości truefalse jako warunków sprawdza się doskonale. Jednak Firebase Security Rules w przypadku usługi Cloud Storage pozwala tworzyć bardziej złożone warunki, które mogą:

  • Sprawdzanie uwierzytelniania użytkowników
  • Weryfikuj dane przychodzące

Uwierzytelnianie

Interfejs Firebase Security Rules dla usługi Cloud Storage integruje się z usługą Firebase Authentication, aby zapewnić zaawansowany uwierzytelnianie oparte na użytkownikach w Cloud Storage. Dzięki temu szczegółowa kontrola dostępu oparta na żądaniach tokena Firebase Authentication.

Gdy uwierzytelniony użytkownik wysyła żądanie do Cloud Storage, zmienna request.auth jest wypełniana wartością uid użytkownika (request.auth.uid) oraz deklaracji tokena JWT Firebase Authentication (request.auth.token).

Dodatkowo, gdy używasz niestandardowego uwierzytelniania, pojawiają się dodatkowe roszczenia. w polu request.auth.token.

Gdy nieuwierzytelniony użytkownik wysyła żądanie, zmienna request.auth ma wartość null.

Korzystając z tych danych, możesz stosować uwierzytelnianie w celu zabezpieczenia plików na kilka sposobów:

  • Public: ignore request.auth
  • Uwierzytelniony prywatny: sprawdź, czy request.auth nie jest typu null
  • Prywatny użytkownik: sprawdź, czy request.auth.uid równa się ścieżce uid
  • Grupa prywatna: sprawdź żądania tokena niestandardowego, aby dopasować je do wybranego roszczenia lub odczytać metadane pliku, aby sprawdzić, czy istnieje pole metadanych

Publiczny

Każda reguła, która nie uwzględnia kontekstu request.auth, może być uznana za regułę public, ponieważ nie uwzględnia kontekstu uwierzytelniania użytkownika. Reguły te mogą być przydatne przy wyświetlaniu danych publicznych, takich jak zasoby gry, dźwięki pliki i inne treści statyczne.

// Anyone to read a public image if the file is less than 100kB
// Anyone can upload a public file ending in '.txt'
match /public/{imageId} {
  allow read: if resource.size < 100 * 1024;
  allow write: if imageId.matches(".*\\.txt");
}

Uwierzytelniony prywatny

W niektórych przypadkach możesz chcieć, aby dane były widoczne dla wszystkich uwierzytelnionych użytkowników przez aplikację, a nie przez nieuwierzytelnionych użytkowników. Od request.auth jest null w przypadku wszystkich nieuwierzytelnionych użytkowników, wystarczy zaznaczyć zmienna request.auth istnieje, aby wymagać uwierzytelniania:

// Require authentication on all internal image reads
match /internal/{imageId} {
  allow read: if request.auth != null;
}

Prywatny użytkownik

Najczęstszym przypadkiem użycia request.auth jest podanie indywidualnych danych użytkowników z określonymi uprawnieniami do plików: z przesyłania zdjęć profilowych czytanie dokumentów prywatnych.

Pliki w folderze Cloud Storage mają pełną „ścieżkę” w pliku danych, aby plik był kontrolowany przez użytkownika, jest unikalnym identyfikatorem informacje z prefiksu nazwy pliku (takie jak uid użytkownika), które mogą zostać sprawdzana podczas sprawdzania reguły:

// Only a user can upload their profile picture, but anyone can view it
match /users/{userId}/profilePicture.png {
  allow read;
  allow write: if request.auth.uid == userId;
}

Prywatna grupa

Innym równie typowym przypadkiem użycia jest przyznanie uprawnień grupie do obiektu, np. umożliwiając kilku członkom zespołu współpracę nad udostępnionym dokumentem. Możesz to zrobić na kilka sposobów:

  • Wygeneruj token niestandardowy Firebase Authentication. zawierający dodatkowe informacje na temat członka grupy (np. identyfikator grupy).
  • Dołącz informacje o grupie (takie jak jej identyfikator lub lista autoryzowanych uid) w metadane pliku,

Gdy te dane zostaną zapisane w tokenie lub metadanych pliku, można się do nich odwoływać z poziomu reguły:

// Allow reads if the group ID in your token matches the file metadata's `owner` property
// Allow writes if the group ID is in the user's custom token
match /files/{groupId}/{fileName} {
  allow read: if resource.metadata.owner == request.auth.token.groupId;
  allow write: if request.auth.token.groupId == groupId;
}

Poproś o ocenę

Przesłane, pobrane, zmiany w metadanych i usunięcie są oceniane na podstawie Wysłano request do: Cloud Storage. Oprócz unikalnego identyfikatora użytkownika ładunek Firebase Authentication w obiekcie request.auth, jak opisano powyżej, zmienna request zawiera ścieżkę pliku, do którego jest wysyłane żądanie, czas otrzymania żądania oraz nową wartość resource. , jeśli żądanie dotyczy zapisu.

Obiekt request zawiera też unikalny identyfikator użytkownika i obiekt ładunek Firebase Authentication w obiekcie request.auth, który zostanie wyjaśniono dokładniej w sekcji Bezpieczeństwo oparte na użytkownikach sekcji dokumentów.

Pełna lista właściwości obiektu request znajduje się poniżej:

Właściwość Typ Opis
auth mapa<ciąg, ciąg> Gdy użytkownik jest zalogowany, podaje uid, jego unikalny identyfikator oraz unikalny identyfikator token, mapa deklaracji JWT (Firebase Authentication). W przeciwnym razie zostanie null
params mapa<ciąg, ciąg> Mapa zawierająca parametry zapytania żądania.
path ścieżka path reprezentujący ścieżkę, do której prowadzi żądanie wykonano na
resource map<string, string> Nowa wartość zasobu, obecna tylko w żądaniach write.
time sygnatura czasowa Sygnatura czasowa określająca czas oceny żądania przez serwer.

Ocena zasobów

Podczas oceny reguł możesz też ocenić metadane pliku przesyłanego, pobieranego, modyfikowanego lub usuwanego. Dzięki temu możesz tworzyć złożone i skuteczne reguły, które na przykład zezwalają na przesyłanie tylko plików z określonymi typami treści lub usuwanie tylko plików o większym rozmiarze.

Parametr Firebase Security Rules dla Cloud Storage zawiera metadane pliku w tagu resource który zawiera pary klucz-wartość metadanych wyświetlanych w tagu Cloud Storage obiekt. Te właściwości można sprawdzać w: read lub write żądania, aby zapewnić integralność danych.

W przypadku żądań write (takich jak przesłanie, aktualizacja lub usunięcie metadanych) w oprócz obiektu resource, który zawiera metadane pliku który obecnie znajduje się na ścieżce żądania, możesz również użyć funkcji Obiekt request.resource, który zawiera podzbiór metadanych pliku jeśli dozwolony jest zapis. Korzystając z tych 2 wartości, możesz zapewnić dane integralności lub egzekwować ograniczenia aplikacji, takie jak typ lub rozmiar pliku.

Pełną listę właściwości obiektu resource znajdziesz poniżej:

Właściwość Typ Opis
name ciąg znaków Pełna nazwa obiektu.
bucket ciąg znaków Nazwa zasobnika, w którym znajduje się ten obiekt.
generation int, Google Cloud Storage generowanie tego obiektu.
metageneration int, Google Cloud Storage przez metagenerację tego obiektu.
size int, Rozmiar obiektu w bajtach.
timeCreated sygnatura czasowa Sygnatura czasowa określająca czas utworzenia obiektu.
updated sygnatura czasowa Sygnatura czasowa określająca czas ostatniej aktualizacji obiektu.
md5Hash ciąg znaków Skrót MD5 obiektu.
crc32c ciąg znaków Skrót crc32c obiektu.
etag ciąg znaków ETag powiązany z tym obiektem.
contentDisposition ciąg znaków Dyspozycja treści powiązana z tym obiektem.
contentEncoding ciąg znaków Kodowanie treści powiązane z tym obiektem.
contentLanguage ciąg znaków Język treści powiązany z tym obiektem.
contentType ciąg znaków Typ treści powiązany z tym obiektem.
metadata map<string, string> Pary klucz-wartość dodatkowych metadanych niestandardowych określonych przez dewelopera.

request.resource zawiera wszystkie te elementy z wyjątkiem generation, metageneration, etag, timeCreated i updated.

Ulepszanie za pomocą Cloud Firestore

Możesz uzyskać dostęp do dokumentów w usłudze Cloud Firestore, aby ocenić inne uprawnienia kryteria.

Dzięki funkcjom firestore.get() i firestore.exists() reguły bezpieczeństwa mogą sprawdzać przychodzące żądania pod kątem dokumentów w Cloud Firestore. Funkcje firestore.get() i firestore.exists() wymagają pełnego określonych ścieżek dokumentów. Gdy używasz zmiennych do budowania ścieżek dla firestore.get() i firestore.exists(), musisz wyraźnie zmienić znaczenie zmiennych korzystających ze składni $(variable).

W poniższym przykładzie widać regułę, która ogranicza dostęp w trybie odczytu do plików członków konkretnych klubów.

service firebase.storage {
  match /b/{bucket}/o {
    match /users/{club}/files/{fileId} {
      allow read: if club in
        firestore.get(/databases/(default)/documents/users/$(request.auth.id)).memberships
    }
  }
}
W następnym przykładzie tylko znajomi użytkownika mogą zobaczyć jego zdjęcia.
service firebase.storage {
  match /b/{bucket}/o {
    match /users/{userId}/photos/{fileId} {
      allow read: if
        firestore.exists(/databases/(default)/documents/users/$(userId)/friends/$(request.auth.id))
    }
  }
}

Gdy utworzysz i zapiszesz pierwsze Cloud Storage Security Rules, które korzystają z tych elementów (Cloud Firestore) funkcji, w konsoli Firebase lub w interfejsie wiersza poleceń Firebase pojawi się prośba o przyznać uprawnienia do połączenia tych dwóch usług.

Aby wyłączyć tę funkcję, usuń rolę uprawnień zgodnie z opisem w sekcji Wdróż aplikację Firebase Security Rules i zarządzaj nią.

Sprawdzanie danych

Firebase Security Rules dla Cloud Storage może też służyć do sprawdzania danych, w tym do weryfikowania nazwy i ścieżki pliku oraz właściwości metadanych pliku, takich jak contentTypesize.

service firebase.storage {
  match /b/{bucket}/o {
    match /images/{imageId} {
      // Only allow uploads of any image file that's less than 5MB
      allow write: if request.resource.size < 5 * 1024 * 1024
                   && request.resource.contentType.matches('image/.*');
    }
  }
}

Funkcje niestandardowe

W miarę jak dane (Firebase Security Rules) stają się bardziej złożone, być może warto pakować zestawy warunków w funkcjach, których możesz używać ponownie w zestawie reguł. Reguły zabezpieczeń i obsługują funkcje niestandardowe. Składnia funkcji niestandardowych jest podobna do składni języka JavaScript, ale funkcje Firebase Security Rules są pisane w języku specyficznym dla danej dziedziny, który ma pewne ważne ograniczenia:

  • Funkcje mogą zawierać tylko jedną instrukcję return. Nie mogą nie zawierają żadnych dodatkowych elementów logicznych. Nie mogą na przykład wykonywać pętli lub zadzwoń do usług zewnętrznych.
  • Funkcje mogą automatycznie uzyskiwać dostęp do funkcji i zmiennych z zakresu, w którym są zdefiniowane. Na przykład funkcja zdefiniowana w argumencie zakres service firebase.storage ma dostęp do resource i tylko w przypadku Cloud Firestore – wbudowane funkcje na przykład get() i exists().
  • Funkcje mogą wywoływać inne funkcje, ale nie mogą się powtarzać. Łączna liczba połączeń głębokość stosu jest ograniczona do 10.
  • W wersji rules2 funkcje mogą definiować zmienne za pomocą słowa kluczowego let. Funkcje mogą mieć dowolną liczbę powiązań let, ale muszą kończyć się zwrotem .

Funkcja jest zdefiniowana za pomocą słowa kluczowego function i przyjmuje zero lub więcej wartości . Możesz na przykład połączyć 2 rodzaje warunków używanych w funkcji w powyższych przykładach w jedną funkcję:

service firebase.storage {
  match /b/{bucket}/o {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }
    match /images/{imageId} {
      allow read, write: if signedInOrPublic();
    }
    match /mp3s/{mp3Ids} {
      allow read: if signedInOrPublic();
    }
  }
}

Używanie funkcji w elementach Firebase Security Rules ułatwia ich utrzymanie, gdy rośnie złożoność reguł.

Dalsze kroki

Po omówieniu warunków możemy uzyskać bardziej zaawansowane rozumieją Zasady i gotowy do:

Dowiedz się, jak obsługiwać podstawowe przypadki użycia i jak wygląda proces tworzenia, testowania i wdrażania reguł: