Ten przewodnik opiera się na przewodniku Uczenie się podstawowej składni języka Firebase Security Rules, aby pokazać, jak dodawać warunki do Firebase Security Rules w przypadku Cloud Storage.
Podstawowym elementem Cloud Storage Security Rules jest warunek. Warunek to wyrażenie logiczne określające, czy dana operacja powinna zostać dozwolona, czy odrzucona. W przypadku prostych reguł stosowanie literalnych wartości true
i false
jako warunków sprawdza się doskonale. Jednak Firebase Security Rules w języku Cloud Storage umożliwia tworzenie bardziej złożonych warunków, które mogą:
- Sprawdzanie uwierzytelniania użytkowników
- Sprawdzanie danych przychodzących
Uwierzytelnianie
Firebase Security Rules dla Cloud Storage integruje się z Firebase Authentication, aby zapewnić Cloud Storage skuteczne uwierzytelnianie użytkowników. Umożliwia to szczegółową kontrolę dostępu na podstawie twierdzeń tokena Firebase Authentication.
Gdy uwierzytelniony użytkownik wysyła żądanie do interfejsu Cloud Storage, zmienna request.auth
jest wypełniana wartością uid
użytkownika (request.auth.uid
), a także deklaracjami tokena JWT Firebase Authentication (request.auth.token
).
Dodatkowo, gdy używasz uwierzytelniania niestandardowego, w polu request.auth.token
wyświetlają się dodatkowe oświadczenia.
Gdy nieuwierzytelniony użytkownik wysyła żądanie, zmienna request.auth
ma wartość null
.
Na podstawie tych danych możesz stosować uwierzytelnianie w celu zabezpieczenia plików na kilka sposobów:
- Public: ignore
request.auth
- Uwierzytelniony dostęp prywatny: sprawdź, czy
request.auth
nie jestnull
- Prywatny użytkownik: sprawdź, czy
request.auth.uid
jest równe ścieżceuid
- Grupa prywatna: sprawdź oświadczenia tokena niestandardowego, aby dopasować wybrane oświadczenie, lub odczytaj 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.
Te reguły mogą być przydatne do wyświetlania publicznych danych, 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"); }
Uwierzytelniona prywatna
W niektórych przypadkach możesz chcieć, aby dane były widoczne dla wszystkich uwierzytelnionych użytkowników aplikacji, ale nie dla niezalogowanych użytkowników. Ponieważ zmienna request.auth
ma wartość null
dla wszystkich niezaufanych użytkowników, wystarczy 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; }
Prywatny użytkownik
Najczęstszym przypadkiem użycia request.auth
będzie przyznanie użytkownikom szczegółowych uprawnień do ich plików: od przesyłania zdjęć profilowych do czytania prywatnych dokumentów.
Ponieważ pliki w Cloud Storage mają pełną „ścieżkę” do pliku, wystarczy, że plik jest kontrolowany przez użytkownika, a w prefiksie nazwy pliku znajduje się unikalny element identyfikujący użytkownika (taki jak uid
użytkownika), który można sprawdzić podczas oceny 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; }
Grupa prywatna
Innym równie częstym przypadkiem użycia jest zezwalanie na uprawnienia grupowe do obiektu, na przykład zezwalanie kilku członkom zespołu na współpracę nad udostępnionym dokumentem. Możesz to zrobić na kilka sposobów:
- Wytwórz Firebase Authentication token niestandardowy, który zawiera dodatkowe informacje o członku grupy (np. identyfikator grupy).
- Uwzględnij informacje o grupie (takie jak identyfikator grupy lub lista autoryzowanych
uid
) w metadanych pliku.
Gdy te dane zostaną zapisane w metadanych tokena lub pliku, można się do nich odwoływać w ramach 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; }
Prośba o ocenę
Przesyłanie, pobieranie, zmiany metadanych i usuwanie są oceniane za pomocą request
wysłanego do Cloud Storage. Oprócz unikalnego identyfikatora użytkownika i ładunku Firebase Authentication w obiekcie request.auth
, jak opisano powyżej, zmienna request
zawiera ścieżkę do pliku, w którym wykonywane jest żądanie, czas otrzymania żądania i nową wartość resource
, jeśli żądanie dotyczy zapisu.
Obiekt request
zawiera też unikalny identyfikator użytkownika oraz dane Firebase Authentication w obiekcie request.auth
, co zostanie wyjaśnione w sekcji Bezpieczeństwo oparte na użytkowniku w dokumentacji.
Pełna lista właściwości obiektu request
znajduje się poniżej:
Właściwość | Typ | Opis |
---|---|---|
auth |
map<string, string> | Gdy użytkownik jest zalogowany, przekazuje uid , czyli swój unikalny identyfikator, oraz token , czyli mapę Firebase Authentication deklaracji JWT. W przeciwnym razie będzie to:null . |
params |
map<string, string> | Mapa zawierająca parametry zapytania żądania. |
path |
ścieżka | path reprezentujący ścieżkę, po której wykonywane jest żądanie. |
resource |
map<string, string> | Nowa wartość zasobu, obecna tylko w przypadku żądań write .
|
time |
sygnatura czasowa | Sygnatura czasowa wskazująca czas serwera, w którym oceniono żądanie. |
Ocena zasobów
Podczas oceny reguł możesz też ocenić metadane pliku, który jest przesyłany, pobierany, modyfikowany lub usuwany. 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.
Firebase Security Rules dla Cloud Storage udostępnia metadane pliku w obiekcie resource
, który zawiera pary klucz-wartość metadanych wyświetlanych w obiekcie Cloud Storage. Te właściwości można sprawdzić w prośbach read
lub
write
, aby zapewnić integralność danych.
W przypadku żądań write
(takich jak przesyłanie, aktualizowanie metadanych i usuwanie) oprócz obiektu resource
, który zawiera metadane pliku znajdującego się obecnie na ścieżce żądania, możesz też użyć obiektu request.resource
, który zawiera podzbiór metadanych pliku do zapisania, jeśli zapis jest dozwolony. Możesz użyć tych 2 wartości, aby zapewnić integralność danych lub zastosować ograniczenia aplikacji, takie jak typ lub rozmiar pliku.
Pełna lista właściwości obiektu resource
znajduje się 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 generacja obiektu tego obiektu. |
metageneration |
int, | Metageneracja obiektu Google Cloud Storage. |
size |
int, | Rozmiar obiektu w bajtach. |
timeCreated |
sygnatura czasowa | Sygnatura czasowa reprezentują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 | Hasz CRC32C obiektu. |
etag |
ciąg znaków | Etag powiązany z tym obiektem. |
contentDisposition |
ciąg znaków | Ustawienie treści powiązane 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 opcje oprócz generation
,
metageneration
, etag
, timeCreated
i updated
.
Ulepsz za pomocą Cloud Firestore
Aby sprawdzić inne kryteria autoryzacji, możesz uzyskać dostęp do dokumentów w Cloud Firestore.
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()
oczekują w pełni określonych ścieżek dokumentów. Jeśli używasz zmiennych do tworzenia ścieżek dla funkcji firestore.get()
i firestore.exists()
, musisz wyraźnie zastosować ukośnik do zmiennych za pomocą składni $(variable)
.
W przykładzie poniżej widzimy regułę, która ogranicza dostęp do odczytu plików do użytkowników należących do 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ą 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 pierwszy Cloud Storage Security Rules, który używa tych funkcji Cloud Firestore, w konsoli Firebase lub w interfejsie wiersza poleceń Firebase pojawi się prośba o włączenie uprawnień umożliwiających połączenie tych dwóch usług.
Możesz wyłączyć tę funkcję, usuwając rolę uprawnień, zgodnie z opisem w sekcji Zarządzanie i wdrażanieFirebase Security Rules.
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 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 Firebase Security Rules stają się bardziej złożone, warto umieszczać zbiory warunków w funkcjach, które można używać wielokrotnie w ramach reguł. Reguły zabezpieczeń 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 jedno wyrażenie
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 zakresie Cloud Firestore – do funkcji wbudowanych, takich jakget()
iexists()
. - Funkcje mogą wywoływać inne funkcje, ale nie mogą być rekurencyjne. Łączna głębokość wywołania zasobnika jest ograniczona do 10.
- W wersji
rules2
funkcje mogą definiować zmienne za pomocą słowa kluczowegolet
. Funkcje mogą zawierać dowolną liczbę instrukcji let, ale muszą kończyć się instrukcją return.
Funkcja jest definiowana za pomocą słowa kluczowego function
i przyjmuje od 0 do nieograniczonej liczby argumentów. Możesz na przykład połączyć 2 typy warunków użytych w przykładach powyżej w jednej funkcji:
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 definicji Firebase Security Rules ułatwia ich utrzymanie, gdy reguły stają się coraz bardziej złożone.
Dalsze kroki
Po tej dyskusji na temat warunków masz już większą wiedzę na temat reguł i możesz:
Dowiedz się, jak obsługiwać podstawowe przypadki użycia i jak wygląda proces tworzenia, testowania i wdrażania reguł:
- Utwórz reguły, które będą odpowiadać typowym scenariuszom.
- Poszerzaj swoją wiedzę, analizując sytuacje, w których musisz wykrywać i unikać niepewnych reguł.
- Testuj reguły za pomocą emulatora Cloud Storage i dedykowanej biblioteki testów reguł zabezpieczeń.
- Zapoznaj się z dostępnymi metodami wdrażania Rules.