Ten przewodnik opiera się na podstawowej składni przewodnika językowego Reguły bezpieczeństwa Firebase, aby pokazać, jak dodać warunki do Reguł bezpieczeństwa Firebase dla Cloud Storage.
Podstawowym elementem składowym Reguł bezpieczeństwa Cloud Storage jest warunek . Warunek to wyrażenie logiczne określające, czy dana operacja powinna być dozwolona, czy zabroniona. W przypadku podstawowych reguł używanie true
i false
literałów jako warunków działa doskonale. Jednak język Firebase Security Rules for Cloud Storage umożliwia pisanie bardziej złożonych warunków, które mogą:
- Sprawdź uwierzytelnianie użytkownika
- Weryfikuj dane przychodzące
Uwierzytelnianie
Reguły bezpieczeństwa Firebase dla Cloud Storage integrują się z uwierzytelnianiem Firebase, aby zapewnić wydajne uwierzytelnianie oparte na użytkownikach w Cloud Storage. Pozwala to na szczegółową kontrolę dostępu na podstawie roszczeń tokena uwierzytelniania Firebase.
Gdy uwierzytelniony użytkownik wysyła żądanie do Cloud Storage, zmienna request.auth
jest wypełniana uid
użytkownika ( request.auth.uid
) oraz żądaniami tokenu uwierzytelniania Firebase ( request.auth.token
).
Ponadto w przypadku korzystania z uwierzytelniania niestandardowego w polu request.auth.token
są wyświetlane dodatkowe oświadczenia.
Gdy nieuwierzytelniony użytkownik wykonuje żądanie, zmienna request.auth
ma wartość null
.
Korzystając z tych danych, istnieje kilka typowych sposobów używania uwierzytelniania do zabezpieczania plików:
- Publiczny: zignoruj
request.auth
- Uwierzytelniony prywatny: sprawdź, czy
request.auth
nie manull
- Prywatny użytkownik: sprawdź, czy
request.auth.uid
jest równe identyfikatorowiuid
- Grupuj prywatnie: sprawdź roszczenia niestandardowego tokena, aby pasowały do wybranego roszczenia, lub przeczytaj metadane pliku, aby zobaczyć, 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 w przypadku udostępniania danych publicznych, takich jak zasoby gry, pliki dźwiękowe lub 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 Twojej 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; }
Użytkownik prywatny
Zdecydowanie najczęstszym przypadkiem użycia request.auth
będzie nadanie 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 unikatowe informacje identyfikujące użytkownika w prefiksie nazwy pliku (takie jak uid
użytkownika), które można sprawdzić kiedy 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:
- Utwórz niestandardowy token Firebase Authentication, który zawiera dodatkowe informacje o członku grupy (takie jak identyfikator grupy)
- Dołącz informacje o grupie (takie jak identyfikator grupy lub lista 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
wysył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ę do pliku, w którym żądanie jest wykonywane, czas otrzymania żądania oraz nową wartość resource
, jeśli prośba jest pisemna.
Obiekt request
zawiera również unikalny identyfikator użytkownika i ładunek uwierzytelniania Firebase w obiekcie request.auth
, co zostanie dokładniej wyjaśnione w sekcji Zabezpieczenia oparte na użytkownikach w dokumentacji.
Pełna lista właściwości w obiekcie request
jest dostępna poniżej:
Nieruchomość | Typ | Opis |
---|---|---|
auth | map<łańcuch, ciąg> | Gdy użytkownik jest zalogowany, podaje uid , unikalny identyfikator użytkownika i token , mapę oświadczeń JWT uwierzytelniania Firebase. W przeciwnym razie będzie to null . |
params | map<łańcuch, ciąg> | Mapa zawierająca parametry zapytania żądania. |
path | ścieżka | path reprezentująca ścieżkę, w której wykonywane jest żądanie. |
resource | map<łańcuch, ciąg> | Nowa wartość zasobu, obecna tylko w żądaniach write . |
time | znak czasu | Sygnatura czasowa reprezentująca czas serwera, w którym żądanie jest oceniane. |
Ocena zasobów
Oceniając reguły, możesz również chcieć ocenić metadane przesyłanego, pobieranego, modyfikowanego lub usuwanego pliku. Pozwala to na tworzenie złożonych i zaawansowanych reguł, które pozwalają np. zezwalać na przesyłanie tylko plików o określonym typie zawartości lub usuwanie tylko plików większych niż określony rozmiar.
Reguły bezpieczeństwa Firebase dla Cloud Storage udostępniają metadane pliku w obiekcie resource
, który zawiera pary klucz/wartość metadanych udostępnianych w obiekcie Cloud Storage. Te właściwości można sprawdzać podczas żądań read
lub write
, aby zapewnić integralność danych.
W przypadku żądań write
(takich jak przesyłanie, aktualizacja metadanych i usuwanie) oprócz obiektu resource
, który zawiera metadane pliku aktualnie istniejącego w ścieżce żądania, masz również możliwość użycia 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
jest dostępna poniżej:
Nieruchomość | Typ | 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 dla tego obiektu. |
metageneration | int | Metageneracja obiektu Google Cloud Storage tego obiektu. |
size | int | Rozmiar obiektu w bajtach. |
timeCreated | znak czasu | Sygnatura czasowa reprezentująca czas utworzenia obiektu. |
updated | znak czasu | Sygnatura czasowa reprezentująca czas ostatniej aktualizacji obiektu. |
md5Hash | strunowy | Skrót MD5 obiektu. |
crc32c | strunowy | Skrót crc32c obiektu. |
etag | strunowy | Etag powiązany z tym obiektem. |
contentDisposition | strunowy | Dyspozycja zawartości powiązana z tym obiektem. |
contentEncoding | strunowy | Kodowanie treści skojarzone z tym obiektem. |
contentLanguage | strunowy | Język zawartości powiązany z tym obiektem. |
contentType | strunowy | Typ zawartości skojarzony z tym obiektem. |
metadata | map<łańcuch, ciąg> | Pary klucz/wartość dodatkowych, określonych przez programistę niestandardowych metadanych. |
request.resource
zawiera je wszystkie 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.
Korzystając z funkcji firestore.get()
i firestore.exists()
, Twoje reguły bezpieczeństwa mogą oceniać przychodzące żądania względem dokumentów w Cloud Firestore. Funkcje firestore.get()
i firestore.exists()
oczekują w pełni określonych ścieżek do dokumentów. Używając zmiennych do konstruowania ścieżek dla firestore.get()
i firestore.exists()
, musisz jawnie uciec przed zmiennymi przy użyciu składni $(variable)
.
W poniższym przykładzie widzimy regułę, która ogranicza dostęp do odczytu plików do użytkowników, którzy są członkami poszczególnych 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)) } } }
Po utworzeniu i zapisaniu pierwszych reguł bezpieczeństwa Cloud Storage, które korzystają z tych funkcji Cloud Firestore, w konsoli Firebase lub interfejsie wiersza polecenia Firebase zostanie wyświetlony monit o przyznanie uprawnień do połączenia tych dwóch produktów.
Możesz wyłączyć tę funkcję, usuwając rolę IAM, zgodnie z opisem w artykule Zarządzanie i wdrażanie reguł bezpieczeństwa Firebase .
Zweryfikuj dane
Reguły bezpieczeństwa Firebase dla Cloud Storage mogą być również używane do sprawdzania poprawności danych, w tym sprawdzania poprawności nazwy i ścieżki pliku, 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 bezpieczeństwa Firebase stają się coraz bardziej złożone, możesz chcieć zawrzeć zestawy warunków w funkcjach, których możesz ponownie używać w swoim zestawie reguł. Reguły bezpieczeństwa obsługują funkcje niestandardowe. Składnia funkcji niestandardowych jest trochę podobna do języka JavaScript, ale funkcje Reguł bezpieczeństwa Firebase są zapisywane w języku specyficznym dla domeny, który ma pewne ważne ograniczenia:
- 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 zostały zdefiniowane. Na przykład funkcja zdefiniowana w zakresie
service firebase.storage
ma dostęp do zmiennejresource
, a tylko w przypadku Cloud Firestore do wbudowanych funkcji, takich jakget()
iexists()
. - Funkcje mogą wywoływać inne funkcje, ale nie mogą się powtarzać. Całkowita głębokość stosu wywołań jest ograniczona do 10.
- W wersji
rules2
funkcje mogą definiować zmienne za pomocą słowa kluczowegolet
. 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żytych 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 Regułach bezpieczeństwa Firebase ułatwia ich konserwację wraz ze wzrostem złożoności reguł.
Następne kroki
Po tym omówieniu warunków masz bardziej wyrafinowane zrozumienie zasad 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ł:
- Napisz reguły, które dotyczą typowych scenariuszy .
- Poszerzaj swoją wiedzę, przeglądając sytuacje, w których musisz wykrywać niebezpieczne reguły i ich unikać .
- Testuj reguły za pomocą emulatora Cloud Storage i dedykowanej biblioteki testów reguł bezpieczeństwa .
- Przejrzyj dostępne metody wdrażania reguł .