Podstawowe zasady bezpieczeństwa

Reguły bezpieczeństwa Firebase pozwalają kontrolować dostęp do przechowywanych danych. Elastyczna składnia reguł oznacza, że ​​możesz tworzyć reguły pasujące do wszystkiego, od wszystkich zapisów do całej bazy danych po operacje na określonym dokumencie.

W tym przewodniku opisano niektóre bardziej podstawowe przypadki użycia, które warto wdrożyć podczas konfigurowania aplikacji i zabezpieczania danych. Jednak zanim zaczniesz pisać reguły, możesz chcieć dowiedzieć się więcej o języku , w którym są napisane, i ich zachowaniu .

Aby uzyskać dostęp do swoich reguł i je zaktualizować, wykonaj czynności opisane w artykule Zarządzanie i wdrażanie reguł bezpieczeństwa Firebase .

Zasady domyślne: tryb zablokowany

Tworząc bazę danych lub instancję magazynu w konsoli Firebase, wybierasz, czy reguły bezpieczeństwa Firebase ograniczają dostęp do Twoich danych ( tryb zablokowany ), czy zezwalają na dostęp każdemu ( tryb testowy ). W Cloud Firestore i Realtime Database domyślne reguły trybu zablokowanego odmawiają dostępu wszystkim użytkownikom. W Cloud Storage dostęp do zasobników mają tylko uwierzytelnieni użytkownicy.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Baza danych czasu rzeczywistego

{
  "rules": {
    ".read": false,
    ".write": false
  }
}

Magazyn w chmurze

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Zasady środowiska programistycznego

Podczas pracy nad aplikacją możesz potrzebować względnie otwartego lub nieskrępowanego dostępu do swoich danych. Pamiętaj tylko, aby zaktualizować reguły przed wdrożeniem aplikacji w środowisku produkcyjnym. Pamiętaj też, że jeśli wdrożysz swoją aplikację, będzie ona dostępna publicznie — nawet jeśli jej nie uruchomiłeś .

Pamiętaj, że Firebase umożliwia klientom bezpośredni dostęp do Twoich danych, a Reguły bezpieczeństwa Firebase to jedyne zabezpieczenie blokujące dostęp złośliwym użytkownikom. Definiowanie reguł niezależnie od logiki produktu ma wiele zalet: klienci nie są odpowiedzialni za egzekwowanie bezpieczeństwa, błędne implementacje nie narażają twoich danych, a co najważniejsze, nie polegasz na serwerze pośredniczącym w ochronie danych przed światem.

Wszyscy uwierzytelnieni użytkownicy

Chociaż nie zalecamy udostępniania danych każdemu zalogowanemu użytkownikowi, podczas opracowywania aplikacji przydatne może być ustawienie dostępu dla dowolnego uwierzytelnionego użytkownika.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Baza danych czasu rzeczywistego

{
  "rules": {
    ".read": "auth.uid !== null",
    ".write": "auth.uid !== null"
  }
}

Magazyn w chmurze

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Reguły gotowe do produkcji

Przygotowując się do wdrożenia aplikacji, upewnij się, że Twoje dane są chronione, a użytkownicy mają odpowiedni dostęp. Wykorzystaj uwierzytelnianie do konfigurowania dostępu opartego na użytkownikach i odczytu bezpośrednio z bazy danych w celu skonfigurowania dostępu opartego na danych.

Rozważ pisanie reguł podczas strukturyzowania danych, ponieważ sposób konfigurowania reguł wpływa na sposób ograniczania dostępu do danych na różnych ścieżkach.

Dostęp tylko dla właściciela treści

Te reguły ograniczają dostęp tylko do uwierzytelnionego właściciela treści. Dane mogą być odczytywane i zapisywane tylko przez jednego użytkownika, a ścieżka danych zawiera identyfikator użytkownika.

Kiedy ta reguła działa: Ta reguła działa dobrze, jeśli dane są wyciszone przez użytkownika — jeśli jedynym użytkownikiem, który potrzebuje dostępu do danych, jest ten sam użytkownik, który je utworzył.

Gdy ta reguła nie działa: Ten zestaw reguł nie działa, gdy wielu użytkowników musi zapisywać lub odczytywać te same dane — użytkownicy nadpisują dane lub nie mogą uzyskać dostępu do utworzonych przez siebie danych.

Aby skonfigurować tę regułę: Utwórz regułę potwierdzającą, że użytkownik żądający dostępu do odczytu lub zapisu danych jest właścicielem tych danych.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow only authenticated content owners access
    match /some_collection/{userId}/{documents=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId
    }
  }
}

Baza danych czasu rzeczywistego

{
  "rules": {
    "some_path": {
      "$uid": {
        // Allow only authenticated content owners access to their data
        ".read": "auth !== null && auth.uid === $uid",
        ".write": "auth !== null && auth.uid === $uid"
      }
    }
  }
}

Magazyn w chmurze

// Grants a user access to a node matching their user ID
service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/path/to/file.txt"
    match /user/{userId}/{allPaths=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

Mieszany dostęp publiczny i prywatny

Ta reguła pozwala każdemu na odczyt zestawu danych, ale ogranicza możliwość tworzenia lub modyfikowania danych w danej ścieżce tylko do uwierzytelnionego właściciela treści.

Kiedy ta reguła działa: Ta reguła działa dobrze w przypadku aplikacji, które wymagają elementów do publicznego odczytu, ale muszą ograniczyć dostęp do edycji do właścicieli tych elementów. Na przykład aplikacja do czatu lub blog.

Kiedy ta reguła nie działa: podobnie jak reguła tylko dla właściciela treści, ten zestaw reguł nie działa, gdy wielu użytkowników musi edytować te same dane. Użytkownicy ostatecznie zastąpią swoje dane.

Aby skonfigurować tę regułę: Utwórz regułę, która umożliwia dostęp do odczytu dla wszystkich użytkowników (lub wszystkich uwierzytelnionych użytkowników) i potwierdza, że ​​użytkownik zapisujący dane jest właścicielem.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow public read access, but only content owners can write
    match /some_collection/{document} {
      allow read: if true
      allow create: if request.auth.uid == request.resource.data.author_uid;
      allow update, delete: if request.auth.uid == resource.data.author_uid;
    }
  }
}

Baza danych czasu rzeczywistego

{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data

  "rules": {
    "some_path": {
      "$uid": {
        ".read": true,
        // or ".read": "auth.uid !== null" for only authenticated users
        ".write": "auth.uid === $uid"
      }
    }
  }
}

Magazyn w chmurze

service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/path/to/file.txt"
    match /user/{userId}/{allPaths=**} {
      allow read;
      allow write: if request.auth.uid == userId;
    }
  }
}

Dostęp oparty na atrybutach i rolach

Aby te reguły działały, musisz zdefiniować i przypisać atrybuty użytkownikom w swoich danych. Reguły bezpieczeństwa Firebase sprawdzają żądanie pod kątem danych z bazy danych lub metadanych pliku, aby potwierdzić lub odmówić dostępu.

Kiedy ta reguła działa: jeśli przypisujesz rolę użytkownikom, ta reguła ułatwia ograniczanie dostępu na podstawie ról lub określonych grup użytkowników. Na przykład, jeśli przechowujesz oceny, możesz przypisać różne poziomy dostępu do grupy „uczniowie” (tylko czytanie ich treści), grupie „nauczyciele” (czytanie i pisanie w swoim przedmiocie) oraz grupie „dyrektorzy” (czytanie cała zawartość).

Kiedy ta reguła nie działa: w Realtime Database i Cloud Storage reguły nie mogą wykorzystywać metody get() , którą mogą uwzględniać reguły Cloud Firestore. W związku z tym musisz ustrukturyzować bazę danych lub metadane pliku, aby odzwierciedlić atrybuty używane w regułach.

Aby skonfigurować tę regułę: W Cloud Firestore umieść w dokumentach użytkowników pole, które możesz czytać, a następnie skonstruuj regułę tak, aby odczytywała to pole i warunkowo udzielała dostępu. W Bazie danych czasu rzeczywistego utwórz ścieżkę danych, która definiuje użytkowników Twojej aplikacji i przyznaje im rolę w węźle podrzędnym.

Możesz także skonfigurować niestandardowe oświadczenia w Uwierzytelnianiu , a następnie pobrać te informacje ze zmiennej auth.token w dowolnych regułach bezpieczeństwa Firebase.

Atrybuty i role zdefiniowane przez dane

Te reguły działają tylko w Cloud Firestore i Realtime Database.

Cloud Firestore

Pamiętaj, że za każdym razem, gdy Twoje reguły obejmują odczyt, tak jak w poniższych regułach, naliczana jest opłata za operację odczytu w Cloud Firestore.

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, Check a boolean `admin` attribute
    allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
    allow read: true;

    // Alterntatively, for role-based access, assign specific roles to users
    match /some_collection/{document} {
     allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
     allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
   }
  }
}

Baza danych czasu rzeczywistego

{
  "rules": {
    "some_path": {
      "${subpath}": {
        //
        ".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
        ".read": true
      }
    }
  }
}

Atrybuty i role roszczeń niestandardowych

Aby wdrożyć te reguły, skonfiguruj niestandardowe roszczenia w Uwierzytelnianiu Firebase, a następnie wykorzystaj roszczenia w swoich regułach.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, check for an admin claim
    allow write: if request.auth.token.admin == true;
    allow read: true;

    // Alterntatively, for role-based access, assign specific roles to users
    match /some_collection/{document} {
     allow read: if request.auth.token.reader == "true";
     allow write: if request.auth.token.writer == "true";
   }
  }
}

Baza danych czasu rzeczywistego

{
  "rules": {
    "some_path": {
      "$uid": {
        // Create a custom claim for each role or group
        // you want to leverage
        ".write": "auth.uid !== null && auth.token.writer === true",
        ".read": "auth.uid !== null && auth.token.reader === true"
      }
    }
  }
}

Magazyn w chmurze

service firebase.storage {
  // 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;
  }
}

Atrybuty najmu

Aby wdrożyć te reguły, skonfiguruj obsługę wielu najemców w Google Cloud Identity Platform (GCIP), a następnie wykorzystaj dzierżawcę w swoich regułach. Poniższe przykłady zezwalają na zapisy od użytkownika w określonej dzierżawie, np. tenant2-m6tyz

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For tenant-based access control, check for a tenantID
    allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
    allow read: true;
  }
}

Baza danych czasu rzeczywistego

{
  "rules": {
    "some_path": {
      "$uid": {
        // Only allow reads and writes if user belongs to a specific tenant
        ".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
        ".read": "auth.uid !== null
      }
    }
  }
}

Magazyn w chmurze

service firebase.storage {
  // Only allow reads and writes if user belongs to a specific tenant
  match /files/{tenantId}/{fileName} {
    allow read: if request.auth != null;
    allow write: if request.auth.token.firebase.tenant == tenantId;
  }
}