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 manull
- Prywatne użytkownika: sprawdź, czy
request.auth.uid
jest równyuid
ś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 zmiennejresource
, a tylko w przypadku Cloud Firestore do funkcji wbudowanych, takich jakget()
iexists()
. - 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 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ż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ł:
- Napisz reguły, które odnoszą się do typowych scenariuszy .
- Bazuj na swojej wiedzy, analizując sytuacje, w których musisz dostrzec i unikać niepewnych Reguł .
- Testuj reguły za pomocą emulatora Cloud Storage i dedykowanej biblioteki testowej Security Rules .
- Przejrzyj dostępne metody wdrażania reguł .