Firebase Security Rules dla Cloud Storage umożliwia kontrolowanie dostępu do obiektów przechowywanych w zasobach Cloud Storage. Elastyczna składnia reguł umożliwia tworzenie reguł, które kontrolują każdą operację, od wszystkich zapisów w Twoim zbiorniku Cloud Storage po operacje na określonym pliku.
W tym przewodniku opisano podstawową składnię i strukturę Cloud Storage Security Rules na potrzeby tworzenia kompletnych zbiorów reguł.
Deklaracja dotycząca usługi i bazy danych
Firebase Security Rules dla Cloud Storage zawsze zaczyna się od tej deklaracji:
service firebase.storage {
// ...
}
Deklaracja service firebase.storage
ogranicza zakres reguł do Cloud Storage, zapobiegając konfliktom między Cloud Storage Security Rules a regułami dotyczącymi innych usług, takich jak Cloud Firestore.
Podstawowe reguły odczytu i zapisu
Podstawowe reguły składają się z instrukcji match
, która identyfikuje zasobniki Cloud Storage, instrukcji dopasowania określającej nazwę pliku oraz wyrażenia allow
, które określa, kiedy odczyt określonych danych jest dozwolony. Wyrażenia allow
określają metody dostępu (np. odczyt, zapis) oraz warunki, na jakich dostęp jest dozwolony lub odmówiony.
W domyślnym zbiorze reguł pierwsze oświadczenie match
używa wyrażenia wieloznacznego {bucket}
, aby wskazać, że reguły dotyczą wszystkich zasobników w projekcie. Więcej informacji o pasowaniu z użyciem symboli wieloznacznych znajdziesz w następnej sekcji.
service firebase.storage {
// The {bucket} wildcard indicates we match files in all Cloud Storage buckets
match /b/{bucket}/o {
// Match filename
match /filename {
allow read: if <condition>;
allow write: if <condition>;
}
}
}
Wszystkie instrukcje dopasowania wskazują pliki. Wyrażenie dopasowania może wskazywać na konkretny plik, jak w przypadku match /images/profilePhoto.png
.
Dopasowywanie symboli wieloznacznych
Oprócz wskazywania pojedynczego pliku pole Rules może używać symboli wieloznacznych, aby wskazywać dowolny plik z danym ciągiem znaków w nazwie, w tym z ukośnikami, jak w przypadku match /images/{imageId}
.
W powyższym przykładzie instrukcja dopasowania używa składni zastępnika {imageId}
.
Oznacza to, że reguła dotyczy każdego pliku, którego nazwa zaczyna się od /images/
, na przykład /images/profilePhoto.png
lub /images/croppedProfilePhoto.png
. Gdy wyrażenia allow
w instrukcji dopasowania zostaną ocenione, zmienna imageId
zostanie zastąpiona nazwą pliku obrazu, np. profilePhoto.png
lub croppedProfilePhoto.png
.
W komponencie match
można odwoływać się do zmiennej wieloznacznej, aby uzyskać uprawnienia do nazwy pliku lub ścieżki:
// Another way to restrict the name of a file
match /images/{imageId} {
allow read: if imageId == "profilePhoto.png";
}
Dane hierarchiczne
Jak już wspomnieliśmy, w zasośniku Cloud Storage nie ma struktury hierarchicznej. Ale dzięki zastosowaniu konwencji nazewnictwa plików, która często obejmuje ukośniki w nazwach plików, możemy odwzorować strukturę przypominającą wbudowany ciąg katalogów i podkatalogów. Musisz wiedzieć, jak Firebase Security Rules działa z tymi nazwami plików.
Rozważ sytuację, w której masz zestaw plików o nazwach zaczynających się od /images/
. Firebase Security Rules mają zastosowanie tylko do dopasowanego pliku, więc kontrola dostępu zdefiniowana w elementach /images/
nie ma zastosowania do elementu /mp3s/
.
Zamiast tego napisz wyraźne reguły, które pasują do różnych wzorów nazw plików:
service firebase.storage {
match /b/{bucket}/o {
match /images/{imageId} {
allow read, write: if <condition>;
}
// Explicitly define rules for the 'mp3s' pattern
match /mp3s/{mp3Id} {
allow read, write: if <condition>;
}
}
}
Gdy zagnieżdżasz instrukcje match
, ścieżka wewnętrznej instrukcji match
jest zawsze dołączana do ścieżki zewnętrznej instrukcji match
. Te 2 zbiory reguł są więc równoważne:
service firebase.storage {
match /b/{bucket}/o {
match /images {
// Exact match for "images/profilePhoto.png"
match /profilePhoto.png {
allow write: if <condition>;
}
}
}
}
service firebase.storage {
match /b/{bucket}/o {
// Exact match for "images/profilePhoto.png"
match /images/profilePhoto.png {
allow write: if <condition>;
}
}
}
Symbole wieloznaczne rekurencyjne
Oprócz symboli wieloznacznych, które dopasowują i zwracają ciągi znaków na końcu nazwy pliku, możesz zadeklarować symbol wieloznaczny z wieloma segmentami, aby uzyskać bardziej złożone dopasowanie. W tym celu dodaj do nazwy symbolu wieloznacznego znak =**
, np. {path=**}
:
// Partial match for files that start with "images"
match /images {
// Exact match for "images/**"
// e.g. images/users/user:12345/profilePhoto.png is matched
// images/profilePhoto.png is also matched!
match /{allImages=**} {
// This rule matches one or more path segments (**)
// allImages is a path that contains all segments matched
allow read: if <other_condition>;
}
}
Jeśli plik spełnia kryteria wielu reguł, wynik jest OR
wszystkich obliczonych reguł. Oznacza to, że jeśli dowolna reguła, która pasuje do pliku, ma wartość true
, wynik jest true
.
W powyżej podanych regułach plik „images/profilePhoto.png” może być odczytywany, jeśli albo condition
, albo other_condition
zwracają wartość „prawda”. Natomiast plik „images/users/user:12345/profilePhoto.png” jest odczytywany tylko wtedy, gdy other_condition
zwraca wartość „prawda”.
Cloud Storage Security Rules nie są stosowane kaskadowo, a reguły są oceniane tylko wtedy, gdy ścieżka żądania pasuje do ścieżki ze zdefiniowanymi regułami.
Wersja 1
Firebase Security Rules domyślnie używa wersji 1. W wersji 1 rekurencyjne symbole wieloznaczne dopasowują co najmniej 1 element nazwy pliku, a nie 0 lub więcej elementów. W związku z tym match /images/{filenamePrefixWildcard}/{imageFilename=**}
pasuje do nazwy pliku, takiej jak /images/profilePics/profile.png, ale nie /images/badge.png. Zamiast tego użyj atrybutu /images/{imagePrefixorFilename=**}
.
Rekurencyjne symbole wieloznaczne muszą znajdować się na końcu oświadczenia o dopasowaniu.
Zalecamy korzystanie z wersji 2 ze względu na jej bardziej zaawansowane funkcje.
Wersja 2
W wersji 2 funkcji Firebase Security Rules rekurencyjne symbole wieloznaczne pasują do 0 lub więcej elementów ścieżki. W ten sposób /images/{filenamePrefixWildcard}/{imageFilename=**}
pasuje do nazw plików /images/profilePics/profile.png i /images/badge.png.
Musisz wyrazić zgodę na wersję 2, dodając rules_version = '2';
na początku swoich reguł zabezpieczeń:
rules_version = '2';
service cloud.storage {
match /b/{bucket}/o {
...
}
}
W każdym elemencie dopasowania może występować maksymalnie 1 rekursywny symbol wieloznaczny, ale w wersji 2 możesz umieścić go w dowolnym miejscu elementu dopasowania. Przykład:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// Matches any file in a songs "subdirectory" under the
// top level of your Cloud Storage bucket.
match /{prefixSegment=**}/songs/{mp3filenames} {
allow read, write: if <condition>;
}
}
}
Operacje szczegółowe
W niektórych sytuacjach warto podzielić operacje read
i write
na bardziej szczegółowe operacje. Aplikacja może na przykład stosować inne warunki tworzenia plików niż ich usuwania.
Operację read
można podzielić na get
i list
.
Regułę write
można podzielić na reguły create
, update
i delete
:
service firebase.storage { match /b/{bucket}/o { // A read rule can be divided into read and list rules match /images/{imageId} { // Applies to single file read requests allow get: if <condition>; // Applies to list and listAll requests (Rules Version 2) allow list: if <condition>; // A write rule can be divided into create, update, and delete rules match /images/{imageId} { // Applies to writes to file contents allow create: if <condition>; // Applies to updates to (pre-existing) file metadata allow update: if <condition>; // Applies to delete operations allow delete: if <condition>; } } } }
Zachodzące na siebie wyrażenia dopasowania
Nazwa pliku może pasować do więcej niż jednego wyrażenia match
. Jeśli wiele wyrażeń allow
pasuje do żądania, dostęp jest udzielany, jeśli co najmniej jedno z tych wyrażeń jest true
:
service firebase.storage {
match b/{bucket}/o {
// Matches file names directly inside of '/images/'.
match /images/{imageId} {
allow read, write: if false;
}
// Matches file names anywhere under `/images/`
match /images/{imageId=**} {
allow read, write: if true;
}
}
}
W podanym przykładzie wszystkie operacje odczytu i zapisu dotyczące plików, których nazwa zaczyna się od /images/
, są dozwolone, ponieważ druga reguła jest zawsze true
, nawet gdy pierwsza reguła jest false
.
Reguły nie są filtrami
Pamiętaj, że po zabezpieczeniu danych i rozpoczęciu wykonywania operacji na plikach reguły zabezpieczeń nie są filtrami. Nie możesz wykonywać operacji na zbiorze plików pasujących do wzorca nazwy i oczekiwać, że Cloud Storage będzie mieć dostęp tylko do plików, do których bieżący klient ma uprawnienia.
Weźmy na przykład taką regułę zabezpieczeń:
service firebase.storage {
match /b/{bucket}/o {
// Allow the client to read files with contentType 'image/png'
match /aFileNamePrefix/{aFileName} {
allow read: if resource.contentType == 'image/png';
}
}
}
Odmowa: ta reguła odrzuca tę prośbę, ponieważ zbiór wyników może zawierać pliki, w których contentType
nie jest image/png
:
Sieć
filesRef = storage.ref().child("aFilenamePrefix"); filesRef.listAll() .then(function(result) { console.log("Success: ", result.items); }) });
Reguły w Cloud Storage Security Rules sprawdzają każde zapytanie pod kątem potencjalnego wyniku i odrzucają żądanie, jeśli może ono zwrócić plik, do którego klient nie ma uprawnień do odczytu. Prośby o dostęp muszą być zgodne z ograniczeniami określonymi przez Twoje reguły.
Dalsze kroki
Możesz lepiej poznać Firebase Security Rules w przypadku Cloud Storage:
Poznaj kolejną ważną koncepcję języka reguł, dynamiczne warunki, które umożliwiają regułom sprawdzanie autoryzacji użytkownika, porównywanie istniejących i przychodzących danych oraz ich weryfikowanie.
Zapoznaj się z typowymi przypadkami użycia dotyczącymi bezpieczeństwa oraz z Firebase Security Rulesdefinicjami, które je opisują.
Możesz zapoznać się z przypadkami użycia Firebase Security Rules dotyczącymi Cloud Storage: