Verwalten und Bereitstellen von Firebase-Sicherheitsregeln

Firebase bietet Ihnen mehrere Tools zum Verwalten Ihrer Regeln, die jeweils in bestimmten Fällen nützlich sind und jeweils dieselbe Back-End-Firebase-Sicherheitsregel-Verwaltungs-API verwenden.

Unabhängig davon, welches Tool zum Aufrufen verwendet wird, die Verwaltungs-API:

  • Nimmt eine Regelquelle auf: eine Reihe von Regeln, in der Regel eine Codedatei mit Firebase-Sicherheitsregelanweisungen.
  • Speichert die aufgenommene Quelle als unveränderlichen Regelsatz .
  • Verfolgt die Bereitstellung jedes Regelsatzes in einer Version . Firebase Security Rules-aktivierte Dienste suchen die Version für ein Projekt, um jede Anfrage für eine gesicherte Ressource zu bewerten.
  • Bietet die Möglichkeit, syntaktische und semantische Tests eines Regelsatzes auszuführen.

Verwenden Sie die Firebase-CLI

Mit der Firebase-Befehlszeilenschnittstelle können Sie lokale Quellen hochladen und Releases bereitstellen. Mit der Firebase Local Emulator Suite der CLI können Sie vollständige lokale Tests von Quellen durchführen .

Die Verwendung der CLI ermöglicht es Ihnen, Ihre Regeln mit Ihrem Anwendungscode unter Versionskontrolle zu halten und Regeln als Teil Ihres bestehenden Bereitstellungsprozesses bereitzustellen.

Generieren Sie eine Konfigurationsdatei

Wenn Sie Ihr Firebase-Projekt mit der Firebase-CLI konfigurieren, erstellen Sie eine .rules Konfigurationsdatei in Ihrem Projektverzeichnis. Verwenden Sie den folgenden Befehl, um mit der Konfiguration Ihres Firebase-Projekts zu beginnen:

Cloud-Firestore

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

Echtzeit-Datenbank

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

Cloud-Speicher

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

Bearbeiten und aktualisieren Sie Ihre Regeln

Bearbeiten Sie Ihre Regelquelle direkt in der .rules Konfigurationsdatei. Stellen Sie sicher, dass alle Änderungen, die Sie in der Firebase-Befehlszeilenschnittstelle vornehmen, in der Firebase-Konsole widergespiegelt werden oder dass Sie Aktualisierungen regelmäßig entweder über die Firebase-Konsole oder die Firebase-Befehlszeilenschnittstelle vornehmen. Andernfalls überschreiben Sie möglicherweise alle in der Firebase-Konsole vorgenommenen Aktualisierungen.

Testen Sie Ihre Aktualisierungen

Die Local Emulator Suite bietet Emulatoren für alle Produkte mit aktivierten Sicherheitsregeln. Die Sicherheitsregel-Engine für jeden Emulator führt sowohl eine syntaktische als auch eine semantische Auswertung von Regeln durch und übertrifft damit die syntaktischen Tests, die die Sicherheitsregel-Verwaltungs-API bietet.

Wenn Sie mit der CLI arbeiten, ist die Suite ein hervorragendes Tool zum Testen von Firebase-Sicherheitsregeln. Verwenden Sie die Local Emulator Suite , um Ihre Updates lokal zu testen und zu bestätigen, dass die Regeln Ihrer App das gewünschte Verhalten zeigen.

Stellen Sie Ihre Updates bereit

Nachdem Sie Ihre Regeln aktualisiert und getestet haben, stellen Sie die Quellen für die Produktion bereit. Verwenden Sie die folgenden Befehle, um Ihre Regeln selektiv allein oder im Rahmen Ihres normalen Bereitstellungsprozesses bereitzustellen.

Cloud-Firestore

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

Echtzeit-Datenbank

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

Cloud-Speicher

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

Verwenden Sie die Firebase-Konsole

Sie können auch Regelquellen bearbeiten und sie als Releases über die Firebase -Konsole bereitstellen. Syntaktische Tests werden während der Bearbeitung in der Benutzeroberfläche der Firebase-Konsole durchgeführt, und Symantic-Tests sind über den Rules Playground verfügbar.

Bearbeiten und aktualisieren Sie Ihre Regeln

  1. Öffnen Sie die Firebase-Konsole und wählen Sie Ihr Projekt aus.
  2. Wählen Sie dann in der Produktnavigation Realtime Database , Cloud Firestore oder Storage aus und klicken Sie dann auf Regeln , um zum Regeleditor zu navigieren.
  3. Bearbeiten Sie Ihre Regeln direkt im Editor.

Testen Sie Ihre Aktualisierungen

Zusätzlich zum Testen der Syntax in der Editor-Benutzeroberfläche können Sie das semantische Rules-Verhalten testen, indem Sie die Datenbank- und Speicherressourcen Ihres Projekts direkt in der Firebase-Konsole mithilfe des Rules Playground verwenden. Öffnen Sie den Bildschirm „Regelspielplatz“ im Regeleditor , ändern Sie die Einstellungen und klicken Sie auf „ Ausführen “ . Suchen Sie nach der Bestätigungsnachricht oben im Editor.

Stellen Sie Ihre Updates bereit

Wenn Sie überzeugt sind, dass Ihre Aktualisierungen Ihren Erwartungen entsprechen, klicken Sie auf Veröffentlichen .

Verwenden Sie das Admin-SDK

Sie können das Admin SDK für Node.js -Regelsätze verwenden . Mit diesem programmgesteuerten Zugriff können Sie:

  • Implementieren Sie benutzerdefinierte Tools, Skripte, Dashboards und CI/CD-Pipelines zur Verwaltung von Regeln.
  • Verwalten Sie Regeln einfacher über mehrere Firebase-Projekte hinweg.

Beim programmgesteuerten Aktualisieren von Regeln ist es sehr wichtig, unbeabsichtigte Änderungen an der Zugriffssteuerung für Ihre App zu vermeiden. Schreiben Sie Ihren Admin SDK-Code unter Berücksichtigung der Sicherheit, insbesondere beim Aktualisieren oder Bereitstellen von Regeln.

Eine weitere wichtige Sache, die Sie beachten sollten, ist, dass die Veröffentlichung von Firebase-Sicherheitsregeln mehrere Minuten dauert, bis sie vollständig verbreitet ist. Achten Sie bei der Verwendung des Admin SDK zum Bereitstellen von Regeln darauf, Race-Bedingungen zu vermeiden, bei denen Ihre App sofort auf Regeln angewiesen ist, deren Bereitstellung noch nicht abgeschlossen ist. Wenn Ihr Anwendungsfall häufige Aktualisierungen der Zugriffssteuerungsregeln erfordert, sollten Sie Lösungen mit Cloud Firestore in Betracht ziehen, die darauf ausgelegt sind, Race-Conditions trotz häufiger Aktualisierungen zu reduzieren.

Beachten Sie auch diese Einschränkungen:

  • Regeln müssen kleiner als 256 KiB UTF-8-codierter Text sein, wenn sie serialisiert werden.
  • Ein Projekt kann insgesamt höchstens 2500 bereitgestellte Regelsätze haben. Sobald dieses Limit erreicht ist, müssen Sie einige alte Regelsätze löschen, bevor Sie neue erstellen können.

Erstellen Sie Cloud Storage- oder Cloud Firestore-Regelsätze und stellen Sie sie bereit

Ein typischer Arbeitsablauf zum Verwalten von Sicherheitsregeln mit dem Admin SDK könnte drei separate Schritte umfassen:

  1. Regeldateiquelle erstellen (optional)
  2. Erstellen Sie einen Regelsatz
  3. Geben Sie den neuen Regelsatz frei oder stellen Sie ihn bereit

Das SDK bietet eine Methode, um diese Schritte in einem einzigen API-Aufruf für Cloud Storage- und Cloud Firestore-Sicherheitsregeln zu kombinieren. Beispielsweise:

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

Dasselbe Muster funktioniert für Cloud Storage-Regeln mit releaseFirestoreRulesetFromSource() .

Alternativ können Sie die Regeldatei als In-Memory-Objekt erstellen, den Regelsatz erstellen und den Regelsatz separat bereitstellen, um diese Ereignisse genauer zu steuern. Beispielsweise:

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

Regelsätze der Echtzeitdatenbank aktualisieren

Um die Regelsätze der Realtime Database mit dem Admin SDK zu aktualisieren, verwenden Sie die Methoden getRules() und setRules() von admin.database . Sie können Regelsätze im JSON-Format oder als Zeichenfolge mit enthaltenen Kommentaren abrufen.

So aktualisieren Sie einen Regelsatz:

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

Regelsätze verwalten

Um die Verwaltung großer Regelsätze zu erleichtern, können Sie mit dem Admin SDK alle vorhandenen Regeln mit admin.securityRules().listRulesetMetadata . Beispielsweise:

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

Für sehr große Bereitstellungen, die im Laufe der Zeit die Grenze von 2500 Regelsätzen erreichen, können Sie eine Logik erstellen, um die ältesten Regeln in einem festen Zeitzyklus zu löschen. So löschen Sie beispielsweise alle Regelsätze, die länger als 30 Tage bereitgestellt wurden:

    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.`);

Verwenden Sie die REST-API

Die oben beschriebenen Tools eignen sich gut für verschiedene Workflows, aber Sie möchten vielleicht Firebase-Sicherheitsregeln mithilfe der Verwaltungs-API selbst verwalten und bereitstellen. Die Verwaltungs-API bietet Ihnen die größte Flexibilität.

Beachten Sie, dass die Veröffentlichung von Firebase-Sicherheitsregeln einige Minuten in Anspruch nehmen kann, um vollständig verbreitet zu werden. Achten Sie bei der Bereitstellung mithilfe der Management-REST-API darauf, Race-Bedingungen zu vermeiden, bei denen Ihre App sofort auf Regeln angewiesen ist, deren Bereitstellung noch nicht abgeschlossen ist.

Beachten Sie auch diese Einschränkungen:

  • Regeln müssen kleiner als 256 KiB UTF-8-codierter Text sein, wenn sie serialisiert werden.
  • Ein Projekt kann insgesamt höchstens 2500 bereitgestellte Regelsätze haben. Sobald dieses Limit erreicht ist, müssen Sie einige alte Regelsätze löschen, bevor Sie neue erstellen können.

Erstellen und implementieren Sie Cloud Storage- oder Cloud Firestore-Regelsätze mit REST

Die Beispiele in diesem Abschnitt verwenden Speicherregeln, obwohl sie auch für Cloud Firestore-Regeln gelten.

Die Beispiele verwenden auch cURL, um API-Aufrufe durchzuführen. Schritte zum Einrichten und Übergeben von Authentifizierungstoken entfallen. Sie können mit dieser API experimentieren, indem Sie den in die Referenzdokumentation integrierten API Explorer verwenden.

Typische Schritte zum Erstellen und Bereitstellen eines Regelsatzes mithilfe der Verwaltungs-API sind:

  1. Erstellen Sie eine Regeldatei Quellen
  2. Erstellen Sie einen Regelsatz
  3. Geben Sie den neuen Regelsatz frei (bereitstellen).

Angenommen, Sie arbeiten an Ihrem Firebase-Projekt „ secure_commerce “ und möchten gesperrte Cloud-Speicherregeln bereitstellen. Sie können diese Regeln in einer Datei storage.rules implementieren.

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

Generieren Sie nun einen Base64-kodierten Fingerabdruck für diese Datei. Sie können dann die Quelle in dieser Datei verwenden, um die Nutzdaten aufzufüllen, die zum Erstellen eines Regelsatzes mit dem REST-Aufruf projects.rulesets.create erforderlich sind. Hier verwenden wir den cat -Befehl, um den Inhalt von storage.rules in die REST-Payload einzufügen.

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'

Die API gibt eine Validierungsantwort und einen Regelsatznamen zurück, z. B. projects/secure_commerce/rulesets/uuid123 . Wenn der Regelsatz gültig ist, besteht der letzte Schritt darin, den neuen Regelsatz in einer benannten Version bereitzustellen.

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'

Aktualisieren Sie Realtime Database-Regelsätze mit REST

Realtime Database bietet eine eigene REST-Schnittstelle zum Verwalten von Regeln. Siehe Verwalten von Firebase-Echtzeitdatenbankregeln über REST .

Regelsätze mit REST verwalten

Um die Verwaltung umfangreicher Regelbereitstellungen zu erleichtern, bietet die Verwaltungs-API zusätzlich zu einer REST-Methode zum Erstellen von Regelsätzen und Versionen Methoden für Folgendes:

  • Regelsätze auflisten, abrufen und löschen
  • Regelversionen auflisten , abrufen und löschen

Für sehr große Bereitstellungen, die im Laufe der Zeit die Grenze von 2500 Regelsätzen erreichen, können Sie eine Logik erstellen, um die ältesten Regeln in einem festen Zeitzyklus zu löschen. Um beispielsweise alle Regelsätze zu löschen, die länger als 30 Tage bereitgestellt wurden, können Sie die Methode projects.rulesets.list aufrufen, die JSON-Liste der Ruleset Objekte anhand ihrer createTime Schlüssel parsen und dann project.rulesets.delete für die entsprechenden Regelsätze nach ruleset_id .

Testen Sie Ihre Updates mit REST

Schließlich können Sie mit der Verwaltungs-API syntaktische und semantische Tests für Cloud Firestore- und Cloud Storage-Ressourcen in Ihren Produktionsprojekten ausführen.

Das Testen mit dieser Komponente der API besteht aus:

  1. Definieren eines TestSuite -JSON-Objekts zur Darstellung einer Reihe von TestCase
  2. Einreichen der TestSuite
  3. Analysieren zurückgegebener TestResult Objekte

Lassen Sie uns ein TestSuite -Objekt mit einem einzelnen TestCase in einer testcase.json -Datei definieren. In diesem Beispiel übergeben wir die Rules-Sprachquelle inline mit der REST-Nutzlast zusammen mit der Testsuite, die für diese Regeln ausgeführt werden soll. Wir spezifizieren eine Regelauswertungserwartung und die Clientanforderung, gegen die der Regelsatz getestet werden soll. Sie können auch angeben, wie vollständig der Testbericht ist, indem Sie den Wert „FULL“ verwenden, um anzugeben, dass Ergebnisse für alle Rules-Sprachausdrücke in den Bericht aufgenommen werden sollen, einschließlich Ausdrücken, die nicht mit der Anfrage abgeglichen wurden.

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

Diese TestSuite können wir dann mit der Methode projects.test zur Evaluierung einreichen.

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

Der zurückgegebene TestReport (der den Status SUCCESS/FAILURE des Tests, Listen von Debug-Meldungen, Listen besuchter Regelausdrücke und ihre Bewertungsberichte enthält) würde mit dem Status SUCCESS bestätigen, dass der Zugriff ordnungsgemäß erlaubt ist.