Schreibbedingungen für Sicherheitsregeln

Diese Anleitung basiert auf dem Leitfaden Sicherheitsregeln strukturieren und zeigt, wie Sie Ihren Firestore-Sicherheitsregeln Bedingungen hinzufügen. Wenn Sie mit den Grundlagen der Firestore-Sicherheitsregeln nicht vertraut sind, lesen Sie den Startleitfaden.

Der primäre Baustein der Firestore-Sicherheitsregeln ist die Bedingung. Eine Bedingung ist ein boolescher Ausdruck, der bestimmt, ob ein bestimmter Vorgang zugelassen oder abgelehnt wird. Verwenden Sie Sicherheitsregeln, um Bedingungen zu schreiben, die die Nutzerauthentifizierung prüfen, eingehende Daten validieren oder sogar auf andere Teile Ihrer Datenbank zugreifen.

Authentifizierung

Eines der gängigsten Sicherheitsregelmuster ist die Zugriffssteuerung basierend auf dem Authentifizierungsstatus des Nutzers. Beispiel: Ihre Anwendung möchte nur angemeldeten Nutzern das Schreiben von Daten erlauben:

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to access documents in the "cities" collection
    // only if they are authenticated.
    match /cities/{city} {
      allow read, write: if request.auth != null;
    }
  }
}

Ein weiteres Muster ist, dass Nutzer nur ihre eigenen Daten lesen und schreiben können:

service cloud.firestore {
  match /databases/{database}/documents {
    // Make sure the uid of the requesting user matches name of the user
    // document. The wildcard expression {userId} makes the userId variable
    // available in rules.
    match /users/{userId} {
      allow read, update, delete: if request.auth != null && request.auth.uid == userId;
      allow create: if request.auth != null;
    }
  }
}

Wenn Ihre Anwendung Firebase Authentication oder die Google Cloud Identity Platform verwendet, enthält die Variable request.auth die Authentifizierungsinformationen für den Client, der Daten anfordert. Weitere Informationen zu request.auth finden Sie in der Referenzdokumentation.

Datenvalidierung

Viele Anwendungen speichern Informationen zur Zugriffssteuerung als Felder in Dokumenten in der Datenbank. Firestore-Sicherheitsregeln können den Zugriff auf der Grundlage von Dokumentdaten dynamisch zulassen oder verweigern:

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to read data if the document has the 'visibility'
    // field set to 'public'
    match /cities/{city} {
      allow read: if resource.data.visibility == 'public';
    }
  }
}

Die Variable resource verweist auf das angeforderte Dokument und resource.data ist eine Zuordnung aller Felder und Werte, die im Dokument gespeichert sind. Weitere Informationen zur Variable resource finden Sie in der Referenzdokumentation.

Wenn Sie Daten schreiben, können Sie eingehende Daten mit vorhandenen Daten vergleichen. Wenn Ihr Regelsatz in diesem Fall den ausstehenden Schreibvorgang zulässt, enthält die Variable request.resource den zukünftigen Status des Dokuments. Bei update-Vorgängen, die nur einen Teil der Dokumentfelder ändern, enthält die Variable request.resource den Status des ausstehenden Dokuments nach dem Vorgang. Sie können die Feldwerte in request.resource prüfen, um unerwünschte oder inkonsistente Datenaktualisierungen zu vermeiden:

service cloud.firestore {
  match /databases/{database}/documents {
    // Make sure all cities have a positive population and
    // the name is not changed
    match /cities/{city} {
      allow update: if request.resource.data.population > 0
                    && request.resource.data.name == resource.data.name;
    }
  }
}

Auf andere Dokumente zugreifen

Mit den Funktionen get() und exists() können Ihre Sicherheitsregeln eingehende Anfragen anhand anderer Dokumente in der Datenbank bewerten. Die Funktionen get() und exists() erwarten vollständig angegebene Dokumentpfade. Wenn Sie Variablen zum Erstellen von Pfaden für get() und exists() verwenden, müssen Sie Variablen mithilfe der Syntax $(variable) explizit maskieren.

Im folgenden Beispiel wird die Variable database von der Übereinstimmungsanweisung match /databases/{database}/documents erfasst und zum Erstellen des Pfads verwendet:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      // Make sure a 'users' document exists for the requesting user before
      // allowing any writes to the 'cities' collection
      allow create: if request.auth != null && exists(/databases/$(database)/documents/users/$(request.auth.uid))

      // Allow the user to delete cities if their user document has the
      // 'admin' field set to 'true'
      allow delete: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true
    }
  }
}

Bei Schreibvorgängen können Sie mit der Funktion getAfter() auf den Status eines Dokuments zugreifen, nachdem eine Transaktion oder ein Batch von Schreibvorgängen, jedoch vor der Transaktion oder dem Batch-Commit abgeschlossen wurde. Wie bei get() wird für die Funktion getAfter() ein vollständig angegebener Dokumentpfad verwendet. Sie können mit getAfter() Gruppen von Schreibvorgängen definieren, die zusammen als Transaktion oder Batch stattfinden müssen.

Zugriffslimits

Pro Regelsatzauswertung ist die Anzahl der Dokumentzugriffsaufrufe begrenzt:

  • 10 für Einzeldokumentanfragen und Abfrageanfragen.
  • 20 für Lesevorgänge, Transaktionen und Batch-Schreibvorgänge für mehrere Dokumente. Das vorherige Limit von 10 gilt auch für jeden Vorgang.

    Angenommen, Sie erstellen eine Batch-Schreibanfrage mit 3 Schreibvorgängen und Ihre Sicherheitsregeln verwenden 2 Dokumentzugriffsaufrufe, um jeden Schreibvorgang zu validieren. In diesem Fall verwendet jeder Schreibvorgang 2 von seinen 10 Zugriffsaufrufen und die Batch-Schreibanfrage 6 von ihren 20 Zugriffsaufrufen.

Das Überschreiten eines dieser Limits führt zu einem Fehler mit Berechtigungsverweigerung. Einige Dokumentzugriffsaufrufe können zwischengespeichert werden. Zwischengespeicherte Aufrufe werden nicht in die Limits einberechnet.

Eine detaillierte Beschreibung der Auswirkungen dieser Limits auf Transaktionen und Batch-Schreibvorgänge finden Sie in der Anleitung zum Sichern von atomaren Vorgängen.

Auf Anrufe und Preise zugreifen

Mit diesen Funktionen wird ein Lesevorgang in Ihrer Datenbank ausgeführt. Das bedeutet, dass Ihnen auch dann Lesevorgänge in Rechnung gestellt werden, wenn Ihre Regeln die Anfrage ablehnen. Weitere Informationen finden Sie unter Firestore-Preise.

Benutzerdefinierte Funktionen

Wenn Ihre Sicherheitsregeln komplexer werden, möchten Sie möglicherweise Gruppen von Bedingungen in Funktionen verpacken, die Sie in Ihrem Regelsatz wiederverwenden können. Sicherheitsregeln unterstützen benutzerdefinierte Funktionen. Die Syntax für benutzerdefinierte Funktionen ähnelt der von JavaScript. Sicherheitsfunktionen werden jedoch in einer domainspezifischen Sprache geschrieben, die einige wichtige Einschränkungen aufweist:

  • Funktionen dürfen nur eine einzige return-Anweisung enthalten. Sie können keine zusätzliche Logik enthalten. Sie können beispielsweise keine Schleifen ausführen oder externe Dienste aufrufen.
  • Funktionen können automatisch auf Funktionen und Variablen aus dem Bereich zugreifen, in dem sie definiert wurden. Eine Funktion, die im Bereich service cloud.firestore definiert ist, hat beispielsweise Zugriff auf die Variable resource und integrierte Funktionen wie get() und exists().
  • Funktionen können andere Funktionen aufrufen, werden aber möglicherweise nicht rekursiv. Die Tiefe des Aufrufstacks ist auf zehn beschränkt.
  • In der Regelversion v2 können Funktionen Variablen mit dem Schlüsselwort let definieren. Funktionen können bis zu zehn Bindungen haben, müssen aber mit einer Rückgabeanweisung enden.

Eine Funktion wird mit dem Keyword function definiert und verwendet null oder mehr Argumente. Beispielsweise können Sie die beiden in den obigen Beispielen verwendeten Bedingungstypen in einer einzigen Funktion kombinieren:

service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

Durch die Verwendung von Funktionen in Ihren Sicherheitsregeln werden sie einfacher zu verwalten, wenn die Komplexität der Regeln zunimmt.

Regeln sind keine Filter

Wenn Sie Ihre Daten sichern und mit dem Schreiben von Abfragen beginnen, denken Sie daran, dass Sicherheitsregeln keine Filter sind. Sie können nicht für alle Dokumente in einer Sammlung eine Abfrage schreiben und erwarten, dass Firestore nur die Dokumente zurückgibt, auf die der aktuelle Client Zugriff hat.

Betrachten Sie beispielsweise die folgende Sicherheitsregel:

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to read data if the document has the 'visibility'
    // field set to 'public'
    match /cities/{city} {
      allow read: if resource.data.visibility == 'public';
    }
  }
}

Abgelehnt: Diese Regel lehnt die folgende Abfrage ab, da die Ergebnismenge Dokumente enthalten kann, in denen visibility nicht public ist:

Web
db.collection("cities").get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            console.log(doc.id, " => ", doc.data());
    });
});

Zugelassen: Diese Regel lässt die folgende Abfrage zu, da die where("visibility", "==", "public")-Klausel garantiert, dass die Ergebnismenge die Bedingung der Regel erfüllt:

Web
db.collection("cities").where("visibility", "==", "public").get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            console.log(doc.id, " => ", doc.data());
        });
    });

Firestore-Sicherheitsregeln werten jede Abfrage anhand ihres potenziellen Ergebnisses aus und schlagen die Anfrage fehl, wenn ein Dokument zurückgegeben werden könnte, für das der Client keine Leseberechtigung hat. Abfragen müssen den Einschränkungen entsprechen, die durch Ihre Sicherheitsregeln festgelegt sind. Weitere Informationen zu Sicherheitsregeln und Abfragen finden Sie unter Daten sicher abfragen.

Mehr zur Verwendung von Google Pay erfahren