Poznaj podstawową składnię języka Firebase Security Rules dla Cloud Storage

Reguły bezpieczeństwa Firebase dla Cloud Storage pozwalają kontrolować dostęp do obiektów przechowywanych w zasobnikach Cloud Storage. Elastyczna składnia reguł pozwala tworzyć reguły sterujące dowolną operacją, od wszystkich zapisów do segmentu Cloud Storage po operacje na określonym pliku.

W tym przewodniku opisano podstawową składnię i strukturę reguł zabezpieczeń Cloud Storage, umożliwiające tworzenie kompletnych zestawów reguł.

Deklaracja usług i baz danych

Reguły bezpieczeństwa Firebase dla Cloud Storage zawsze zaczynają się od następującej deklaracji:

service firebase.storage {
    // ...
}

Deklaracja service firebase.storage obejmuje reguły Cloud Storage, zapobiegając konfliktom między regułami bezpieczeństwa Cloud Storage a regułami innych produktów, takich jak Cloud Firestore.

Podstawowe zasady odczytu/zapisu

Podstawowe reguły składają się z instrukcji match identyfikującej zasobniki Cloud Storage, instrukcji dopasowania określającej nazwę pliku oraz wyrażenia allow określającego, kiedy dozwolone jest odczytywanie określonych danych. wyrażenia allow określają metody dostępu (np. odczyt, zapis) oraz warunki , w których dostęp jest dozwolony lub zabroniony.

W domyślnym zestawie reguł pierwsza instrukcja match używa wyrażenia wieloznacznego {bucket} , aby wskazać, że reguły mają zastosowanie do wszystkich zasobników w Twoim projekcie. W następnej sekcji omówimy więcej idei dopasowań z symbolami wieloznacznymi.

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ą na pliki. Instrukcja match może wskazywać na konkretny plik, tak jak w przypadku match /images/profilePhoto.png .

Dopasuj symbole wieloznaczne

Oprócz wskazywania pojedynczego pliku Reguły mogą używać symboli wieloznacznych do wskazywania dowolnego pliku z podanym przedrostkiem w nazwie, łącznie z ukośnikami, jak w przypadku match /images/{imageId} .

W powyższym przykładzie instrukcja match używa składni wieloznacznej {imageId} . Oznacza to, że reguła ma zastosowanie do każdego pliku z /images/ na początku nazwy, na przykład /images/profilePhoto.png lub /images/croppedProfilePhoto.png . Po ocenie wyrażeń allow w instrukcji match zmienna imageId zostanie przetłumaczona na nazwę pliku obrazu, taką jak profilePhoto.png lub croppedProfilePhoto.png .

Z match można odwoływać się do zmiennej wieloznacznej, aby zapewnić autoryzację 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 powiedzieliśmy wcześniej, w zasobniku Cloud Storage nie ma struktury hierarchicznej. Jednak stosując konwencję nazewnictwa plików, często zawierającą ukośniki w nazwach plików, możemy naśladować strukturę wyglądającą jak zagnieżdżona seria katalogów i podkatalogów. Ważne jest, aby zrozumieć, w jaki sposób reguły bezpieczeństwa Firebase współdziałają z tymi nazwami plików.

Rozważmy sytuację zbioru plików, których nazwy zaczynają się od rdzenia /images/ . Reguły bezpieczeństwa Firebase mają zastosowanie tylko do dopasowanej nazwy pliku, więc kontrola dostępu zdefiniowana w rdzeniu /images/ nie ma zastosowania do rdzenia /mp3s/ . Zamiast tego napisz jawne reguły, które pasują do różnych wzorcó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>;
    }
  }
}

Podczas zagnieżdżania instrukcji match ścieżka wewnętrznej instrukcji match jest zawsze dodawana do ścieżki zewnętrznej instrukcji match . Dlatego poniższe dwa zestawy reguł są 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>;
      }
  }
}

Rekurencyjne symbole wieloznaczne dopasowania

Oprócz symboli wieloznacznych, które dopasowują i zwracają ciągi znaków na końcu nazwy pliku, można zadeklarować wielosegmentowy symbol wielosegmentowy w celu bardziej złożonego dopasowania, dodając =** do nazwy symbolu wieloznacznego, 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 do pliku pasuje wiele reguł, wynikiem jest OR wyniku wszystkich ocen reguł. Oznacza to, że jeśli jakakolwiek reguła, do której pasuje plik, ma wartość true , wynikiem jest true .

W powyższych regułach plik „images/profilePhoto.png” można odczytać, jeśli którykolwiek condition lub other_condition ma wartość true, podczas gdy plik „images/users/user:12345/profilePhoto.png” podlega jedynie wynikowi other_condition .

Reguły zabezpieczeń Cloud Storage nie są kaskadowane, a reguły są oceniane tylko wtedy, gdy ścieżka żądania odpowiada ścieżce z określonymi regułami.

Wersja 1

Reguły zabezpieczeń Firebase domyślnie korzystają z wersji 1. W wersji 1 rekurencyjne symbole wieloznaczne dopasowują jeden lub więcej elementów nazwy pliku, a nie zero lub więcej elementów. Zatem match /images/{filenamePrefixWildcard}/{imageFilename=**} dopasowuje nazwę pliku taką jak /images/profilePics/profile.png, ale nie /images/badge.png. Zamiast tego użyj /images/{imagePrefixorFilename=**} .

Rekurencyjne symbole wieloznaczne muszą znajdować się na końcu instrukcji dopasowania.

Zalecamy używanie wersji 2 ze względu na jej bardziej zaawansowane funkcje.

Wersja 2

W wersji 2 reguł bezpieczeństwa Firebase rekurencyjne symbole wieloznaczne dopasowują zero lub więcej elementów ścieżki. Zatem /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 górze reguł bezpieczeństwa:

rules_version = '2';
service cloud.storage {
  match /b/{bucket}/o {
   ...
 }
}

Na instrukcję dopasowania możesz mieć maksymalnie jeden rekurencyjny symbol wieloznaczny, ale w wersji 2 możesz umieścić ten symbol wieloznaczny w dowolnym miejscu instrukcji dopasowania. Na 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 granularne

W niektórych sytuacjach przydatne jest podzielenie read i write na bardziej szczegółowe operacje. Na przykład Twoja aplikacja może chcieć wymusić inne warunki podczas tworzenia pliku niż przy jego usuwaniu.

Operację read można podzielić na get i list .

Regułę write można podzielić na 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>;
    }
  }
 }
}

Nakładające się instrukcje dopasowania

Możliwe jest, że nazwa pliku będzie pasować do więcej niż jednej instrukcji match . W przypadku, gdy do żądania pasuje wiele wyrażeń allow , dostęp jest dozwolony, jeśli true jest którykolwiek z warunków:

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 powyższym przykładzie wszystkie odczyty i zapisy w plikach, których nazwa zaczyna się od /images/ są dozwolone, ponieważ druga reguła jest zawsze true , nawet jeśli pierwsza reguła jest false .

Reguły to nie filtry

Gdy zabezpieczysz swoje dane i zaczniesz wykonywać operacje na plikach, pamiętaj, że reguły bezpieczeństwa to nie filtry. Nie możesz wykonywać operacji na zestawie plików pasujących do wzorca nazwy pliku i oczekiwać, że Cloud Storage uzyska dostęp tylko do plików, do których bieżący klient ma uprawnienia dostępu.

Weźmy na przykład następującą regułę bezpieczeństwa:

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 następujące żądanie, ponieważ zestaw wyników może zawierać pliki, 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 regułach zabezpieczeń Cloud Storage oceniają każde zapytanie pod kątem potencjalnego wyniku i odrzucają żądanie, jeśli mogłoby zwrócić plik, do którego odczytania klient nie ma uprawnień. Żądania dostępu muszą spełniać ograniczenia określone przez Twoje reguły.

Następne kroki

Możesz pogłębić swoją wiedzę na temat reguł bezpieczeństwa Firebase dotyczących przechowywania w chmurze:

  • Poznaj kolejną ważną koncepcję języka Reguł, warunków dynamicznych, które pozwalają Regułom sprawdzać autoryzację użytkownika, porównywać istniejące i przychodzące dane, weryfikować przychodzące dane i nie tylko.

  • Przejrzyj typowe przypadki użycia zabezpieczeń i definicje reguł zabezpieczeń Firebase, które je dotyczą .

Możesz poznać przypadki użycia reguł bezpieczeństwa Firebase specyficzne dla Cloud Storage: