Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

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

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

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 Cloud Storage.

Podstawowym elementem składowym reguł zabezpieczeń 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 dodatkowe oświadczenia są wyświetlane w polu request.auth.token .

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 zostać uznana 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 aplikacji, ale nie dla użytkowników nieuwierzytelnionych. 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 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 dane te 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ę

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 zapisem. 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 , który zostanie wyjaśniony 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, które mają zostać zapisane, 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 skojarzona 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 .

Ulepsz dzięki Cloud Firestore

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

Używając funkcji firestore.get() i firestore.exists() , Twoje reguły bezpieczeństwa mogą oceniać przychodzące żądania względem dokumentów w Cloud Firestore. Obie funkcje firestore.get() i firestore.exists() oczekują w pełni określonych ścieżek dokumentów. Używając zmiennych do konstruowania ścieżek dla funkcji firestore.get() i firestore.exists() , musisz jawnie zmienić znaczenie zmiennych przy użyciu składni $(variable) .

W poniższym przykładzie widzimy regułę, która ogranicza dostęp do odczytu plików do tych użytkowników, którzy są członkami określonych 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ą oglądać swoje 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))
    }
  }
}

Po utworzeniu i zapisaniu pierwszych reguł zabezpieczeń Cloud Storage, które korzystają z tych funkcji Cloud Firestore, w konsoli Firebase lub w interfejsie wiersza polecenia Firebase pojawi się monit o zezwolenie na połączenie tych dwóch produktów.

Możesz wyłączyć tę funkcję, usuwając rolę uprawnień zgodnie z opisem w sekcji Zarządzanie i wdrażanie reguł zabezpieczeń Firebase .

Sprawdź poprawność danych

Reguły zabezpieczeń Firebase dla Cloud Storage mogą być również używane do sprawdzania poprawności danych, w tym sprawdzania 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 Twoje 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ł: