Ten przewodnik opiera się na podstawowej składni przewodnika językowego Firebase Security Rules i pokazuje, jak dodawać warunki do reguł zabezpieczeń Firebase dla Cloud Storage.
Podstawowym elementem Reguł zabezpieczeń Cloud Storage jest warunek . Warunek to wyrażenie logiczne określające, czy dana operacja powinna być dozwolona, czy zabroniona. W przypadku podstawowych zasad używanie literałów true
i false
jako warunków sprawdza się doskonale. Jednak język Firebase Security Rules for Cloud Storage umożliwia pisanie bardziej złożonych warunków, które mogą:
- Sprawdź uwierzytelnienie użytkownika
- Zweryfikuj przychodzące dane
Uwierzytelnianie
Reguły bezpieczeństwa Firebase dla Cloud Storage integrują się z uwierzytelnianiem Firebase, aby zapewnić skuteczne uwierzytelnianie oparte na użytkownikach w Cloud Storage. Pozwala to na szczegółową kontrolę dostępu w oparciu o oświadczenia tokena uwierzytelniania Firebase.
Gdy uwierzytelniony użytkownik wysyła żądanie do Cloud Storage, zmienna request.auth
jest wypełniana uid
użytkownika użytkownika ( request.auth.uid
), a także oświadczeniami tokenu JWT uwierzytelniania Firebase ( 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 wartość null
.
Korzystając z tych danych, istnieje kilka popularnych sposobów korzystania z uwierzytelniania w celu zabezpieczenia plików:
- Publiczne: zignoruj
request.auth
- Uwierzytelniony prywatny: sprawdź, czy
request.auth
nie manull
- Użytkownik prywatny: sprawdź, czy
request.auth.uid
jest równy identyfikatorowi użytkownikauid
- Grupa prywatna: sprawdź oświadczenia tokena niestandardowego, aby pasowały do wybranego roszczenia lub przeczytaj metadane pliku, aby sprawdzić, czy pole metadanych istnieje
Publiczny
Każdą regułę, która nie uwzględnia kontekstu request.auth
, można uznać za regułę public
, ponieważ nie uwzględnia ona 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 użytkowników nieuwierzytelnionych. Ponieważ zmienna request.auth
ma null
dla wszystkich nieuwierzytelnionych 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; }
Użytkownik prywatny
Zdecydowanie najczęstszym przypadkiem użycia request.auth
będzie zapewnienie indywidualnym 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, aby plik był kontrolowany przez użytkownika, wystarczy informacja identyfikująca użytkownika w przedrostku nazwy pliku (taka jak uid
użytkownika), którą 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 częstym przypadkiem użycia będzie zezwolenie na uprawnienia grupowe do obiektu, na przykład zezwolenie kilku członkom zespołu na współpracę nad udostępnionym dokumentem. Można to zrobić na kilka sposobów:
- Wytwórz niestandardowy token uwierzytelniania Firebase, który zawiera dodatkowe informacje o członku grupy (takie jak identyfikator grupy)
- Uwzględnij informacje o grupie (takie jak identyfikator grupy lub lista autoryzowanych
uid
) w metadanych pliku
Po zapisaniu tych danych w metadanych tokenu lub 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 usunięcia są oceniane na podstawie request
wysył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 żądanie jest wykonywane, godzinę otrzymania żądania oraz nową wartość resource
, jeśli prośba jest pisemna.
Obiekt request
zawiera także unikalny identyfikator użytkownika i ładunek Firebase Authentication w obiekcie request.auth
, co zostanie wyjaśnione szczegółowo w sekcji dokumentacji dotyczącej zabezpieczeń opartych na użytkownikach .
Pełna lista właściwości w obiekcie request
dostępna jest poniżej:
Nieruchomość | Typ | Opis |
---|---|---|
auth | mapa<ciąg, ciąg> | Gdy użytkownik jest zalogowany, podaje uid , unikalny identyfikator użytkownika i token , czyli mapę roszczeń JWT uwierzytelniania Firebase. W przeciwnym razie będzie 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 oceniane jest żądanie. |
Ocena zasobów
Oceniając reguły, możesz także chcieć ocenić metadane przesyłanego, pobieranego, modyfikowanego lub usuwanego pliku. Umożliwia to tworzenie złożonych i wydajnych reguł, które na przykład zezwalają 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 zabezpieczeń Firebase dla Cloud Storage udostępniają metadane pliku w obiekcie resource
, który zawiera pary klucz/wartość metadanych wyświetlanych w obiekcie Cloud Storage. Właściwości te można sprawdzić w żądaniach 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 istniejącego aktualnie w ścieżce żądania, masz także możliwość wykorzystania obiektu request.resource
, który zawiera podzbiór metadanych pliku, który ma zostać zapisany, 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ść | Typ | Opis |
---|---|---|
name | strunowy | Pełna nazwa obiektu |
bucket | strunowy | Nazwa segmentu, w którym znajduje się ten obiekt. |
generation | wew | Generowanie obiektu Google Cloud Storage dla tego obiektu. |
metageneration | wew | Metageneracja obiektu Google Cloud Storage dla tego obiektu. |
size | wew | 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 | Hash MD5 obiektu. |
crc32c | strunowy | Hash crc32c obiektu. |
etag | strunowy | Etag powiązany z tym obiektem. |
contentDisposition | strunowy | Dyspozycja treś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 powiązany z tym obiektem. |
metadata | mapa<ciąg, ciąg> | Pary klucz/wartość dodatkowych, niestandardowych metadanych określonych przez programistę. |
request.resource
zawiera 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.
Dzięki funkcjom firestore.get()
i firestore.exists()
reguły bezpieczeństwa mogą oceniać 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. Używając zmiennych do konstruowania ścieżek dla firestore.get()
i firestore.exists()
, musisz jawnie uciec od zmiennych, używając składni $(variable)
.
W poniższym przykładzie widzimy regułę ograniczającą dostęp do odczytu plików tylko użytkownikom będącym 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 korzystających z funkcji Cloud Firestore zostaniesz poproszony w konsoli Firebase lub interfejsie CLI Firebase o włączenie uprawnień do połączenia obu produktów.
Możesz wyłączyć tę funkcję, usuwając rolę IAM, zgodnie z opisem w artykule Zarządzanie i wdrażanie reguł zabezpieczeń Firebase .
Zweryfikuj dane
Reguł bezpieczeństwa Firebase dla Cloud Storage można również używać do sprawdzania poprawności danych, w tym sprawdzania 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 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 całym zestawie reguł. Reguły bezpieczeństwa obsługują funkcje niestandardowe. Składnia funkcji niestandardowych przypomina trochę JavaScript, ale funkcje reguł bezpieczeństwa Firebase są napisane 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 ma wbudowane funkcje, takie 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. Możesz na przykład 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 bezpieczeństwa Firebase sprawia, że są one łatwiejsze w utrzymaniu w miarę wzrostu złożoności reguł.
Następne kroki
Po 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 dotyczące typowych scenariuszy .
- Opieraj się na swojej wiedzy, przeglądając sytuacje, w których musisz wykryć i unikać niepewnych Reguł .
- Testuj reguły za pomocą emulatora Cloud Storage i dedykowanej biblioteki testowej Reguł Bezpieczeństwa .
- Przejrzyj dostępne metody wdrażania reguł .