Podstawowe reguły zabezpieczeń

Firebase Security Rules umożliwiają kontrolowanie dostępu do przechowywanych danych. Dzięki elastycznemu składnikowi reguł możesz tworzyć reguły, które pasują do wszystkiego, od wszystkich zapisów w całej bazie danych po operacje na konkretnym dokumencie.

W tym przewodniku opisano niektóre podstawowe przypadki użycia, które warto zastosować podczas konfigurowania aplikacji i ochrony danych. Zanim jednak zaczniesz pisać reguły, dowiedz się więcej o języku, w którym są one pisane, oraz o ich zachowaniu.

Aby uzyskać dostęp do reguł i je aktualizować, wykonaj czynności opisane w artykule Zarządzanie regułami Firebase Security Rules.

Reguły domyślne: tryb blokady

Podczas tworzenia bazy danych lub instancji magazynu w konsoli Firebase możesz wybrać, czy Firebase Security Rules ma ograniczać dostęp do Twoich danych (tryb zablokowany) czy zezwolić 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 usłudze Cloud Storage tylko uwierzytelnieni użytkownicy mają dostęp do zasobników miejsca na dane.

Cloud Firestore

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

Realtime Database

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

Cloud Storage

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

Reguły dotyczące środowiska programistycznego

Podczas pracy nad aplikacją możesz potrzebować stosunkowo otwartego lub nieograniczonego dostępu do danych. Przed wdrożeniem aplikacji w wersji produkcyjnej zaktualizuj Rules. Pamiętaj też, że jeśli wdrożysz aplikację, będzie ona publicznie dostępna, nawet jeśli nie jej uruchomisz.

Pamiętaj, że Firebase umożliwia klientom bezpośredni dostęp do Twoich danych, a Firebase Security Rules są jedyną ochroną przed dostępem użytkowników o złośliwych zamiarach. Definiowanie reguł oddzielnie od logiki usługi ma wiele zalet: klienci nie są odpowiedzialni za egzekwowanie zabezpieczeń, błędne implementacje nie będą stanowić zagrożenia dla Twoich danych, a co najważniejsze, nie musisz polegać na serwerze pośredniczącym, aby chronić dane przed światem zewnętrznym.

Wszyscy uwierzytelnieni użytkownicy

Nie zalecamy udostępniania danych wszystkim zalogowanym użytkownikom, ale podczas tworzenia aplikacji może być przydatne zezwalanie na dostęp wszystkim uwierzytelnionym użytkownikom.

Cloud Firestore

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

Realtime Database

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

Cloud Storage

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

Reguły gotowe do wykorzystania w środowisku produkcyjnym

Przygotowując się do wdrożenia aplikacji, zadbaj o ochronę danych i prawidłowe przyznanie dostępu użytkownikom. Aby skonfigurować dostęp na podstawie użytkownika, użyj opcji Authentication, a aby skonfigurować dostęp na podstawie danych, odczytuj dane bezpośrednio z bazy danych.

Zastanów się nad sformułowaniem reguł podczas tworzenia struktury danych, ponieważ sposób ich konfigurowania 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 są tylko do odczytu i zapisu przez jednego użytkownika, a ścieżka danych zawiera identyfikator użytkownika.

Kiedy działa ta reguła: ta reguła działa dobrze, jeśli dane są oddzielone od innych danych według użytkownika – jeśli dostęp do danych ma mieć tylko użytkownik, który je stworzył.

Kiedy 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 będą nadpisywać dane lub nie będą mieć do nich dostępu.

Aby skonfigurować tę regułę: utwórz regułę, która potwierdza, że użytkownik, który prosi o dostęp 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
    }
  }
}

Realtime Database

{
  "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"
      }
    }
  }
}

Cloud Storage

// 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;
    }
  }
}

Dostęp mieszany (publiczny i prywatny)

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

Kiedy działa ta reguła: ta reguła sprawdza się w przypadku aplikacji, które wymagają publicznie dostępnych elementów, ale muszą ograniczać dostęp do edycji tych elementów do ich właścicieli. Może to być na przykład aplikacja do czatu lub blog.

Kiedy ta reguła nie działa: podobnie jak reguła dotycząca tylko właściciela treści, ta reguła nie działa, gdy wiele osób musi edytować te same dane. W efekcie użytkownicy będą zastępować dane innych użytkowników.

Aby skonfigurować tę regułę: utwórz regułę, która umożliwia odczyt wszystkim użytkownikom (lub wszystkim uwierzytelnionych użytkownikom), i potwierdź, ż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 public reads
      allow read: if true
      // Allow creation if the current user owns the new document
      allow create: if request.auth.uid == request.resource.data.author_uid;
      // Allow updates by the owner, and prevent change of ownership
      allow update: if request.auth.uid == request.resource.data.author_uid
                    && request.auth.uid == resource.data.author_uid;
      // Allow deletion if the current user owns the existing document
      allow delete: if request.auth.uid == resource.data.author_uid;
    }
  }
}

Realtime Database

{
// 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"
      }
    }
  }
}

Cloud Storage

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ć atrybuty i przypisać je do użytkowników w swoich danych. Firebase Security Rulessprawdzają żądanie na podstawie danych z Twojej bazy danych lub metadanych pliku, aby potwierdzić lub odmówić dostępu.

Kiedy działa ta reguła: jeśli przypisujesz użytkownikom role, ta reguła ułatwia ograniczanie dostępu na podstawie ról lub określonych grup użytkowników. Jeśli na przykład przechowujesz oceny, możesz przypisać różne poziomy dostępu do grupy „uczniowie” (tylko do odczytu), grupy „nauczyciele” (do odczytu i zapisu w temacie) oraz grupy „dyrektorzy” (do odczytu wszystkich treści).

Kiedy ta reguła nie działa: w wersjach Realtime DatabaseCloud Storage reguły nie mogą korzystać z metody get(), której mogą używać reguły Cloud Firestore. Dlatego musisz uporządkować metadane bazy danych lub pliku, aby odzwierciedlały atrybuty używane w regułach.

Aby skonfigurować tę regułę:Cloud Firestore uwzględnij pole w dokumentach użytkowników, które możesz odczytać, a następnie ułóż regułę, aby odczytać to pole i warunkowo przyznać dostęp. W Realtime Database utwórz ścieżkę danych, która definiuje użytkowników aplikacji i przypisuje im rolę w węźle podrzędnym.

Możesz też skonfigurować specyficzne oświadczenia w Authentication, a potem pobierać te informacje z zmiennej auth.token w dowolnym elemencie Firebase Security Rules.

Atrybuty i role zdefiniowane na podstawie danych

Te reguły działają tylko w Cloud FirestoreRealtime Database.

Cloud Firestore

Pamiętaj, że za każdym razem, gdy Twoje reguły zawierają operację odczytu, taką jak te poniżej, będziesz obciążany opłatą 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"
   }
  }
}

Realtime Database

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

Atrybuty i role dotyczące zgłoszeń niestandardowych

Aby zastosować te reguły, skonfiguruj oświadczenia niestandardoweFirebase Authentication, a potem wykorzystaj te oświadczenia 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";
   }
  }
}

Realtime Database

{
  "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"
      }
    }
  }
}

Cloud Storage

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 dotyczące dzierżawy

Aby zastosować te reguły, skonfiguruj środowisko wielu najemców w Google Cloud Identity Platform (GCIP), a następnie użyj najemcy w regułach. W tych przykładach operacje zapisu są dozwolone dla użytkownika w konkretnym kliencie, 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;
  }
}

Realtime Database

{
  "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
      }
    }
  }
}

Cloud Storage

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;
  }
}