Check out what’s new from Firebase at Google I/O 2022. Learn more

Warunki użytkowania w regułach bezpieczeństwa Firebase Cloud Storage

Ten przewodnik opiera się na poznaniu podstawowej składni przewodnika językowego reguł zabezpieczeń Firebase, aby pokazać, jak dodawać warunki do reguł zabezpieczeń Firebase dla usługi Cloud Storage.

Podstawowym elementem składowym reguł bezpieczeństwa Cloud Storage jest warunek . Warunek to wyrażenie logiczne, które określa, czy dana operacja powinna być dozwolona, ​​czy zabroniona. W przypadku podstawowych reguł użycie true i false literałów jako warunków działa doskonale. Ale język reguł zabezpieczeń Firebase dla Cloud Storage umożliwia tworzenie bardziej złożonych warunków, które mogą:

  • Sprawdź uwierzytelnianie użytkownika
  • Sprawdź poprawność danych przychodzących

Uwierzytelnianie

Reguły zabezpieczeń Firebase dla Cloud Storage integrują się z uwierzytelnianiem Firebase, aby zapewnić zaawansowane uwierzytelnianie oparte na użytkownikach w Cloud Storage. Pozwala to na szczegółową kontrolę dostępu na podstawie oświadczeń tokena uwierzytelniania Firebase.

Gdy uwierzytelniony użytkownik wykonuje żądanie w Cloud Storage, zmienna request.auth jest wypełniana identyfikatorem użytkownika ( request.auth.uid ) oraz oświadczeniami tokena JWT uwierzytelniania uid ( request.auth.token ).

Ponadto w przypadku korzystania z uwierzytelniania niestandardowego w polu request.auth.token pojawiają się dodatkowe oświadczenia.

Gdy nieuwierzytelniony użytkownik wykonuje żądanie, zmienna request.auth ma null .

Korzystając z tych danych, istnieje kilka typowych sposobów wykorzystania uwierzytelniania w celu zabezpieczenia plików:

  • Publiczny: ignoruj request.auth
  • Uwierzytelniony prywatny: sprawdź, czy request.auth nie ma null
  • Prywatne użytkownika: sprawdź, czy request.auth.uid jest równy uid ścieżki
  • Grupa prywatna: sprawdź oświadczenia tokena niestandardowego, aby pasowały do ​​wybranego oświadczenia, lub przeczytaj metadane pliku, aby sprawdzić, czy istnieje pole metadanych

Publiczny

Każda reguła, która nie uwzględnia kontekstu request.auth , może być uważana za regułę public , ponieważ nie uwzględnia kontekstu uwierzytelniania użytkownika. Reguły te mogą być przydatne do ujawniania danych publicznych, takich jak zasoby gier, pliki dźwiękowe lub inna zawartość statyczna.

// 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 Twojej aplikacji, ale nie dla nieuwierzytelnionych użytkowników. Ponieważ zmienna request.auth ma null dla wszystkich nieuwierzytelnionych użytkowników, wszystko, co musisz zrobić, to sprawdzić, czy zmienna request.auth istnieje, aby wymagać uwierzytelnienia:

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

Prywatne użytkownika

Zdecydowanie najczęstszym przypadkiem użycia request.auth będzie zapewnienie poszczególnym użytkownikom szczegółowych uprawnień do ich plików: od przesyłania zdjęć profilowych po czytanie prywatnych dokumentów.

Ponieważ pliki w Cloud Storage mają pełną „ścieżkę” do pliku, wszystko, czego potrzeba, aby plik był kontrolowany przez użytkownika, to fragment unikalnych informacji identyfikujących użytkownika w prefiksie nazwy pliku (takich jak uid użytkownika ), które można sprawdzić gdy reguła jest oceniana:

// 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;
}

Grupa prywatna

Innym równie powszechnym przypadkiem użycia będzie przyznanie uprawnień grupowych do obiektu, na przykład umożliwienie kilku członkom zespołu współpracy nad udostępnionym dokumentem. Można to zrobić na kilka sposobów:

  • Wygeneruj niestandardowy token uwierzytelniania Firebase, który zawiera dodatkowe informacje o członku grupy (takie jak identyfikator grupy)
  • Dołącz informacje o grupie (takie jak identyfikator grupy lub listę autoryzowanych uid ) w metadanych pliku

Gdy te dane są przechowywane 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ę

Przesyłanie, pobieranie, zmiany metadanych i usuwanie są oceniane na podstawie request wysłanego do Cloud Storage. Oprócz unikalnego identyfikatora użytkownika i ładunku uwierzytelniania Firebase w obiekcie request.auth , jak opisano powyżej, zmienna request zawiera ścieżkę pliku, w którym żądanie jest wykonywane, czas odebrania żądania oraz nową wartość resource , jeśli prośba jest pisemna. Uwzględniono również nagłówki HTTP i stan uwierzytelniania.

Obiekt request zawiera również unikalny identyfikator użytkownika i ładunek uwierzytelniania Firebase w obiekcie request.auth , co zostanie wyjaśnione w dalszej części dokumentu w sekcji Bezpieczeństwo oparte na użytkowniku .

Pełna lista właściwości w obiekcie request jest dostępna poniżej:

Nieruchomość Rodzaj Opis
auth mapa<ciąg, ciąg> Gdy użytkownik jest zalogowany, udostępnia uid , unikalny identyfikator użytkownika i token , mapę oświadczeń JWT uwierzytelniania Firebase. W przeciwnym razie będzie to null .
params mapa<ciąg, ciąg> Mapa zawierająca parametry zapytania żądania.
path ścieżka path reprezentująca ścieżkę, na której wykonywane jest żądanie.
resource mapa<ciąg, ciąg> Nowa wartość zasobu, obecna tylko w żądaniach write .
time znak czasu Znacznik czasu reprezentujący czas serwera, w którym żądanie jest oceniane.

Ocena zasobów

Podczas oceny reguł możesz również chcieć ocenić metadane przesyłanego, pobieranego, modyfikowanego lub usuwanego pliku. Pozwala to na tworzenie złożonych i potężnych reguł, które pozwalają na przesyłanie tylko plików z określonymi typami treści lub usuwanie tylko plików większych niż określony rozmiar.

Reguły zabezpieczeń Firebase dla Cloud Storage udostępniają metadane plików w obiekcie resource , które zawierają pary klucz/wartość metadanych pojawiających się w obiekcie Cloud Storage. Te właściwości można sprawdzać w żądaniach read lub write , aby zapewnić integralność danych.

W przypadku żądań write (takich jak przesyłanie, aktualizacje metadanych i usuwanie) oprócz obiektu resource , który zawiera metadane pliku dla pliku, który aktualnie istnieje w ścieżce żądania, masz również możliwość korzystania z obiektu request.resource , który zawiera podzbiór metadanych pliku do zapisania, jeśli zapis jest dozwolony. Możesz użyć tych dwóch wartości, aby zapewnić integralność danych lub wymusić ograniczenia aplikacji, takie jak typ lub rozmiar pliku.

Pełna lista właściwości w obiekcie resource dostępna jest poniżej:

Nieruchomość Rodzaj Opis
name strunowy Pełna nazwa obiektu
bucket strunowy Nazwa zasobnika, w którym znajduje się ten obiekt.
generation int Generowanie obiektu Google Cloud Storage tego obiektu.
metageneration int Metageneracja obiektu Google Cloud Storage tego obiektu.
size int Rozmiar obiektu w bajtach.
timeCreated znak czasu Znacznik czasu reprezentujący czas utworzenia obiektu.
updated znak czasu Znacznik czasu reprezentujący czas ostatniej aktualizacji obiektu.
md5Hash strunowy Skrót MD5 obiektu.
crc32c strunowy Skrót crc32c obiektu.
etag strunowy etag skojarzony z tym obiektem.
contentDisposition strunowy Dyspozycja zawartości powiązana z tym obiektem.
contentEncoding strunowy Kodowanie treści powiązane z tym obiektem.
contentLanguage strunowy Język treści powiązany z tym obiektem.
contentType strunowy Typ zawartości skojarzony z tym obiektem.
metadata mapa<ciąg, ciąg> 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 .

Sprawdź poprawność danych

Reguły bezpieczeństwa Firebase dla Cloud Storage mogą być również używane do walidacji danych, w tym walidacji nazwy pliku i ścieżki, a także właściwości metadanych pliku, takich jak contentType i size .

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 reguły zabezpieczeń Firebase stają się coraz bardziej złożone, możesz chcieć otoczyć zestawy warunków funkcjami, które możesz ponownie wykorzystać w swoim zestawie reguł. Reguły bezpieczeństwa obsługują funkcje niestandardowe. Składnia funkcji niestandardowych przypomina trochę JavaScript, ale funkcje reguł zabezpieczeń Firebase są napisane w języku specyficznym dla domeny, który ma kilka ważnych ograniczeń:

  • Funkcje mogą zawierać tylko jedną instrukcję return . Nie mogą zawierać żadnej dodatkowej logiki. Na przykład nie mogą wykonywać pętli ani wywoływać 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 zakresie service firebase.storage ma dostęp do zmiennej resource , a tylko w przypadku Cloud Firestore do funkcji wbudowanych, takich jak get() i exists() .
  • Funkcje mogą wywoływać inne funkcje, ale nie mogą rekursywnie. Całkowita głębokość stosu wywołań 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ę instrukcją return.

Funkcja jest definiowana za pomocą słowa kluczowego function i przyjmuje zero lub więcej argumentów. Na przykład możesz chcieć połączyć dwa typy warunków użyte 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();
    }
  }
}

Korzystanie z funkcji w regułach zabezpieczeń Firebase sprawia, że ​​są one łatwiejsze w utrzymaniu w miarę wzrostu złożoności reguł.

Następne kroki

Po tym omówieniu warunków masz bardziej wyrafinowane zrozumienie reguł i jesteś gotowy do:

Dowiedz się, jak radzić sobie z podstawowymi przypadkami użycia i poznaj przepływ pracy podczas opracowywania, testowania i wdrażania reguł: