Zarządzaj regułami bezpieczeństwa Firebase i wdrażaj je

Firebase udostępnia kilka narzędzi do zarządzania regułami, z których każde jest przydatne w określonych przypadkach, a każde korzysta z tego samego interfejsu API zarządzania regułami bezpieczeństwa Firebase na zapleczu.

Bez względu na to, które narzędzie zostanie użyte do jego wywołania, API do zarządzania:

  • Pozyskuje źródło reguł : zestaw reguł, zazwyczaj plik kodu zawierający instrukcje reguł zabezpieczeń Firebase.
  • Przechowuje przetworzone źródło jako niezmienny zestaw reguł .
  • Śledzi wdrażanie każdego zestawu reguł w wydaniu . Usługi obsługujące reguły zabezpieczeń Firebase wyszukują wersję projektu, aby ocenić każde żądanie zabezpieczonego zasobu.
  • Zapewnia możliwość uruchamiania testów składniowych i semantycznych zestawu reguł.

Użyj interfejsu wiersza polecenia Firebase

Dzięki Firebase CLI możesz przesyłać lokalne źródła i wdrażać wydania . Pakiet Firebase Local Emulator Suite w CLI umożliwia przeprowadzenie pełnego lokalnego testowania źródeł .

Korzystanie z interfejsu wiersza polecenia umożliwia kontrolowanie wersji reguł za pomocą kodu aplikacji i wdrażanie reguł w ramach istniejącego procesu wdrażania.

Wygeneruj plik konfiguracyjny

Podczas konfigurowania projektu Firebase za pomocą interfejsu wiersza polecenia Firebase tworzysz plik konfiguracyjny .rules w katalogu projektu. Użyj następującego polecenia, aby rozpocząć konfigurowanie projektu Firebase:

Cloud Firestore

// Set up Firestore in your project directory, creates a .rules file
firebase init firestore

Baza danych czasu rzeczywistego

// Set up Realtime Database in your project directory, creates a .rules file
firebase init database

Magazyn w chmurze

// Set up Storage in your project directory, creates a .rules file
firebase init storage

Edytuj i aktualizuj swoje zasady

Edytuj źródło reguł bezpośrednio w pliku konfiguracyjnym .rules . Upewnij się, że wszelkie zmiany wprowadzane w interfejsie wiersza poleceń Firebase są odzwierciedlane w konsoli Firebase lub stale wprowadzasz aktualizacje za pomocą konsoli Firebase lub interfejsu wiersza polecenia Firebase. W przeciwnym razie możesz zastąpić wszelkie aktualizacje wprowadzone w konsoli Firebase.

Przetestuj swoje aktualizacje

Pakiet lokalnych emulatorów zawiera emulatory dla wszystkich produktów obsługujących reguły zabezpieczeń. Silnik reguł bezpieczeństwa dla każdego emulatora dokonuje oceny zarówno składniowej, jak i semantycznej reguł, tym samym przewyższając testowanie składniowe oferowane przez API zarządzania regułami bezpieczeństwa.

Jeśli pracujesz z CLI, pakiet jest doskonałym narzędziem do testowania reguł zabezpieczeń Firebase. Użyj lokalnego pakietu emulatorów , aby przetestować aktualizacje lokalnie i potwierdzić, że reguły aplikacji wykazują pożądane zachowanie.

Wdróż aktualizacje

Po zaktualizowaniu i przetestowaniu reguł wdróż źródła w środowisku produkcyjnym. Użyj poniższych poleceń, aby selektywnie wdrożyć same reguły lub wdrożyć je w ramach normalnego procesu wdrażania.

Cloud Firestore

// Deploy your .rules file
firebase deploy --only firestore:rules

Baza danych czasu rzeczywistego

// Deploy your .rules file
firebase deploy --only database

Magazyn w chmurze

// Deploy your .rules file
firebase deploy --only storage

Użyj konsoli Firebase

Możesz także edytować źródła reguł i wdrażać je jako wersje z konsoli Firebase. Testy syntaktyczne są przeprowadzane podczas edycji w interfejsie konsoli Firebase, a testy syntaktyczne są dostępne za pomocą Placu zabaw reguł.

Edytuj i aktualizuj swoje zasady

  1. Otwórz konsolę Firebase i wybierz swój projekt.
  2. Następnie wybierz Baza danych czasu rzeczywistego , Cloud Firestore lub Pamięć z nawigacji produktu, a następnie kliknij Reguły , aby przejść do edytora reguł.
  3. Edytuj swoje reguły bezpośrednio w edytorze.

Przetestuj swoje aktualizacje

Oprócz testowania składni w interfejsie użytkownika edytora możesz testować zachowanie reguł semantycznych, korzystając z zasobów bazy danych i magazynu projektu, bezpośrednio w konsoli Firebase, korzystając z Rules Playground . Otwórz ekran Zasady Playground w Edytorze reguł, zmodyfikuj ustawienia i kliknij Uruchom . Poszukaj wiadomości z potwierdzeniem w górnej części edytora.

Wdróż aktualizacje

Gdy uznasz, że Twoje aktualizacje są zgodne z oczekiwaniami, kliknij Opublikuj .

Użyj pakietu Admin SDK

Możesz użyć pakietu Admin SDK dla zestawów reguł Node.js . Dzięki temu programowemu dostępowi możesz:

  • Implementuj niestandardowe narzędzia, skrypty, pulpity nawigacyjne i potoki CI/CD do zarządzania regułami.
  • Łatwiej zarządzaj regułami w wielu projektach Firebase.

Podczas programowego aktualizowania reguł bardzo ważne jest unikanie niezamierzonych zmian w kontroli dostępu do aplikacji. Napisz kod pakietu Admin SDK, mając na uwadze przede wszystkim bezpieczeństwo, zwłaszcza podczas aktualizowania lub wdrażania reguł.

Inną ważną rzeczą, o której należy pamiętać, jest to, że pełne rozpowszechnienie reguł zabezpieczeń Firebase zajmuje kilka minut. Korzystając z pakietu Admin SDK do wdrażania reguł, unikaj sytuacji wyścigowych, w których aplikacja natychmiast opiera się na regułach, których wdrażanie nie zostało jeszcze zakończone. Jeśli Twój przypadek użycia wymaga częstych aktualizacji reguł kontroli dostępu, rozważ rozwiązania korzystające z Cloud Firestore, którego celem jest ograniczenie wyścigów pomimo częstych aktualizacji.

Zwróć także uwagę na te ograniczenia:

  • Podczas serializacji reguły muszą być mniejsze niż 256 KiB tekstu zakodowanego w UTF-8.
  • Projekt może mieć maksymalnie 2500 wdrożonych zestawów reguł. Po osiągnięciu tego limitu musisz usunąć niektóre stare zestawy reguł przed utworzeniem nowych.

Twórz i wdrażaj zestawy reguł Cloud Storage lub Cloud Firestore

Typowy przepływ pracy zarządzania regułami bezpieczeństwa za pomocą pakietu Admin SDK może obejmować trzy odrębne kroki:

  1. Utwórz źródło pliku reguł (opcjonalnie)
  2. Utwórz zestaw reguł
  3. Wydanie lub wdrożenie nowego zestawu reguł

Pakiet SDK udostępnia metodę łączenia tych kroków w jedno wywołanie interfejsu API dla reguł bezpieczeństwa Cloud Storage i Cloud Firestore. Na przykład:

    const source = `service cloud.firestore {
      match /databases/{database}/documents {
        match /carts/{cartID} {
          allow create: if request.auth != null && request.auth.uid == request.resource.data.ownerUID;
          allow read, update, delete: if request.auth != null && request.auth.uid == resource.data.ownerUID;
        }
      }
    }`;
    // Alternatively, load rules from a file
    // const fs = require('fs');
    // const source = fs.readFileSync('path/to/firestore.rules', 'utf8');

    await admin.securityRules().releaseFirestoreRulesetFromSource(source);

Ten sam wzorzec działa w przypadku reguł Cloud Storage z releaseFirestoreRulesetFromSource() .

Alternatywnie można utworzyć plik reguł jako obiekt w pamięci, utworzyć zestaw reguł i wdrożyć zestaw reguł osobno, aby lepiej kontrolować te zdarzenia. Na przykład:

    const rf = admin.securityRules().createRulesFileFromSource('firestore.rules', source);
    const rs = await admin.securityRules().createRuleset(rf);
    await admin.securityRules().releaseFirestoreRuleset(rs);

Aktualizuj zestawy reguł Bazy danych czasu rzeczywistego

Aby zaktualizować zestawy reguł Bazy danych czasu rzeczywistego za pomocą pakietu Admin SDK, użyj getRules() i setRules() z admin.database . Możesz pobrać zestawy reguł w formacie JSON lub jako ciąg z dołączonymi komentarzami.

Aby zaktualizować zestaw reguł:

    const source = `{
      "rules": {
        "scores": {
          ".indexOn": "score",
          "$uid": {
            ".read": "$uid == auth.uid",
            ".write": "$uid == auth.uid"
          }
        }
      }
    }`;
    await admin.database().setRules(source);

Zarządzaj zestawami reguł

Aby ułatwić zarządzanie dużymi zestawami reguł, pakiet Admin SDK umożliwia wyświetlanie wszystkich istniejących reguł za pomocą admin.securityRules().listRulesetMetadata . Na przykład:

    const allRulesets = [];
    let pageToken = null;
    while (true) {
      const result = await admin.securityRules().listRulesetMetadata(pageToken: pageToken);
      allRulesets.push(...result.rulesets);
      pageToken = result.nextPageToken;
      if (!pageToken) {
        break;
      }
    }

W przypadku bardzo dużych wdrożeń, które z czasem osiągną limit zestawu reguł 2500, można utworzyć logikę, aby usunąć najstarsze reguły w ustalonym cyklu czasowym. Na przykład, aby usunąć wszystkie zestawy reguł wdrożone dłużej niż 30 dni:

    const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS);
    const promises = [];
    allRulesets.forEach((rs) => {
      if (new Date(rs.createTime) < thirtyDays) {
        promises.push(admin.securityRules().deleteRuleset(rs.name));
      }
    });
    await Promise.all(promises);
    console.log(`Deleted ${promises.length} rulesets.`);

Użyj interfejsu API REST

Opisane powyżej narzędzia dobrze nadają się do różnych przepływów pracy, ale możesz chcieć zarządzać i wdrażać reguły zabezpieczeń Firebase przy użyciu samego interfejsu API zarządzania. Zarządzanie API zapewnia największą elastyczność.

Pamiętaj, że pełne rozpowszechnienie wersji reguł zabezpieczeń Firebase zajmuje kilka minut. Korzystając z interfejsu API zarządzania REST do wdrażania, należy unikać sytuacji wyścigu, w których aplikacja natychmiast opiera się na regułach, których wdrażanie nie zostało jeszcze zakończone.

Zwróć także uwagę na te ograniczenia:

  • Podczas serializacji reguły muszą być mniejsze niż 256 KiB tekstu zakodowanego w UTF-8.
  • Projekt może mieć maksymalnie 2500 wdrożonych zestawów reguł. Po osiągnięciu tego limitu musisz usunąć niektóre stare zestawy reguł przed utworzeniem nowych.

Twórz i wdrażaj zestawy reguł Cloud Storage lub Cloud Firestore za pomocą REST

Przykłady w tej sekcji wykorzystują reguły pamięci masowej, ale dotyczą one również reguł Cloud Firestore.

Przykłady używają również cURL do wykonywania wywołań API. Pominięto kroki konfiguracji i przekazywania tokenów uwierzytelniania. Możesz poeksperymentować z tym interfejsem API za pomocą Eksploratora API zintegrowanego z dokumentacją referencyjną .

Typowe kroki tworzenia i wdrażania zestawu reguł przy użyciu interfejsu API zarządzania to:

  1. Utwórz źródła plików reguł
  2. Utwórz zestaw reguł
  3. Wydaj (wdróż) nowy zestaw reguł

Załóżmy, że pracujesz nad projektem secure_commerce i chcesz wdrożyć zablokowane reguły Cloud Storage. Reguły te można zaimplementować w pliku storage.rules .

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

Teraz wygeneruj odcisk palca zakodowany w base64 dla tego pliku. Następnie możesz użyć źródła w tym pliku, aby wypełnić ładunek potrzebny do utworzenia zestawu reguł za pomocą wywołania REST projects.rulesets.create . Tutaj używamy polecenia cat , aby wstawić zawartość storage.rules do ładunku REST.

curl -X POST -d '{
  "source": {
    {
      "files": [
        {
          "content": "' $(cat storage.rules) '",
          "name": "storage.rules",
          "fingerprint": <sha fingerprint>
        }
      ]
    }
  }
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets'

Interfejs API zwraca odpowiedź weryfikacyjną i nazwę zestawu reguł, na przykład projects/secure_commerce/rulesets/uuid123 . Jeśli zestaw reguł jest prawidłowy, ostatnim krokiem jest wdrożenie nowego zestawu reguł w nazwanej wersji.

curl -X POST -d '{
  "name": "projects/secure_commerce/releases/prod/v23   "  ,
  "rulesetName": "projects/secure_commerce/rulesets/uuid123",
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'

Aktualizuj zestawy reguł Bazy danych czasu rzeczywistego za pomocą REST

Baza danych czasu rzeczywistego zapewnia własny interfejs REST do zarządzania regułami. Zobacz Zarządzanie regułami bazy danych czasu rzeczywistego Firebase przez REST .

Zarządzaj zestawami reguł za pomocą REST

Aby ułatwić zarządzanie dużymi wdrożeniami reguł, oprócz metody REST służącej do tworzenia zestawów reguł i wydań, interfejs API zarządzania udostępnia metody:

  • wyświetlaj, pobieraj i usuwaj zestawy reguł
  • wyświetlaj, pobieraj i usuwaj wydania reguł

W przypadku bardzo dużych wdrożeń, które z czasem osiągną limit zestawu reguł 2500, można utworzyć logikę, aby usunąć najstarsze reguły w ustalonym cyklu czasowym. Na przykład, aby usunąć wszystkie zestawy reguł wdrożone na dłużej niż 30 dni, możesz wywołać metodę projects.rulesets.list , przeanalizować listę JSON obiektów zestawu reguł na ich kluczach Ruleset , a następnie wywołać createTime na odpowiednich ruleset_id reguł przez project.rulesets.delete .

Przetestuj swoje aktualizacje za pomocą REST

Wreszcie interfejs API zarządzania umożliwia przeprowadzanie testów składniowych i semantycznych zasobów Cloud Firestore i Cloud Storage w projektach produkcyjnych.

Testowanie za pomocą tego komponentu API składa się z:

  1. Definiowanie obiektu JSON TestSuite do reprezentowania zestawu obiektów TestCase
  2. Przesyłanie TestSuite
  3. Parsowanie zwróconych obiektów TestResult

Zdefiniujmy obiekt TestSuite z pojedynczym TestCase w pliku testcase.json . W tym przykładzie przekazujemy źródło języka Rules wraz z ładunkiem REST wraz z zestawem testów do uruchomienia na tych regułach. Określamy oczekiwanie na ocenę Reguł oraz żądanie klienta, względem którego ma być testowany zestaw reguł. Możesz również określić stopień kompletności raportu testowego, używając wartości „FULL”, aby wskazać wyniki dla wszystkich wyrażeń w języku Reguł, które powinny być uwzględnione w raporcie, w tym wyrażeń, które nie zostały dopasowane do żądania.

 {
  "source":
  {
    "files":
    [
      {
        "name": "firestore.rules",
        "content": "service cloud.firestore {
          match /databases/{database}/documents {
            match /users/{userId}{
              allow read: if (request.auth.uid == userId);
            }
            function doc(subpath) {
              return get(/databases/$(database)/documents/$(subpath)).data;
            }
            function isAccountOwner(accountId) {
              return request.auth.uid == accountId 
                  || doc(/users/$(request.auth.uid)).accountId == accountId;
            }
            match /licenses/{accountId} {
              allow read: if isAccountOwner(accountId);
            }
          }
        }"
      }
    ]
  },
  "testSuite":
  {
    "testCases":
    [
      {
        "expectation": "ALLOW",
        "request": {
           "auth": {"uid": "123"},
           "path": "/databases/(default)/documents/licenses/abcd",
           "method": "get"},
        "functionMocks": [
            {
            "function": "get",
            "args": [{"exact_value": "/databases/(default)/documents/users/123"}],
            "result": {"value": {"data": {"accountId": "abcd"}}}
            }
          ]
      }
    ]
  }
}

Następnie możemy przesłać ten TestSuite do oceny za pomocą metody projects.test .

curl -X POST -d '{
    ' $(cat testcase.json) '
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets/uuid123:test'

Zwrócony TestReport (zawierający status testu SUCCESS/FAILURE, listy komunikatów debugowania, listy odwiedzonych wyrażeń reguł i ich raporty z oceny) potwierdzałby statusem SUCCESS, że dostęp jest dozwolony.