Pipeline-Vorgänge bieten zwar eine Vielzahl von Funktionen, die Regel-Engine ist jedoch auf die Erkennung von Vergleichsfiltern (z.B. >) und logischen Filtern (z.B. or) beschränkt, um die Erfüllbarkeit von Einschränkungen und die Sicherheit zu gewährleisten.
Unterstützte Filterausdrücke
Damit Pipelinevorgänge auf die von Ihren Regeln festgelegten Grenzen beschränkt werden, müssen logische und Vergleichsoperatoren für Konstanten verwendet werden. Die folgenden Filtertypen werden von der Regel-Engine erkannt:
- Vergleiche:
eq,neq,gt,gte,lt,lte,in,arrayContains. - Logisch:
and,or.
Hier einige Beispiele:
where(eq("foo", 2))where(lt("foo", 2))documents("/user/1", "/user/2").where(...)
Anfrageattribute
Sie können das Objekt request weiterhin verwenden, um die Authentifizierung und den Abfragekontext zu validieren. Einige in Standardabfragen verfügbare Attribute werden jedoch in Pipeline-Vorgängen nicht unterstützt.
Unterstützte Properties
Die neue Engine unterstützt weiterhin die folgenden Properties:
request.auth: Zugriff auf Nutzer-UID und Token-Daten.request.method: Identifiziert den Vorgang (z. B.get,list).request.path: Der Pfad der Ressource, auf die zugegriffen wird.request.time: Der serverseitige Zeitstempel der Anfrage.
Nicht unterstützte Properties
Die request.query-Eigenschaften wie limit, offset und orderBy werden für Regelprüfungen von Pipelinevorgängen nicht unterstützt, da es komplex ist, diese Werte in mehrstufigen Abfragen zu bestimmen.
Umgang mit Pipelinephasen und Berechtigungen
Es gibt verschiedene Pipelinephasen, die bestimmten detaillierten Vorgängen in Sicherheitsregeln zugeordnet sind:
allow list-Berechtigungen: Werden durch die Phasencollection(),collectionGroup()unddatabase()ausgelöst.allow get-Berechtigungen: Werden durch die Phasedocuments()ausgelöst, die ähnlich wie ein Batch-get-Vorgang behandelt wird.allow create-Berechtigungen: Werden durchinsert()-Phasen undupsert()-Phasen beim Erstellen neuer Dokumente ausgelöst.allow update-Berechtigungen: Werden durchupdate()-Phasen undupsert()-Phasen ausgelöst, wenn vorhandene Dokumente aktualisiert werden.allow delete-Berechtigungen: Ausgelöst durchdelete()Phasen.allow write-Berechtigungen: Gilt für alle DML-Vorgänge (insert(),update(),upsert()unddelete()).- Literalphase: Die
literals()-Phase liest nicht aus der Datenbank, kann aber Kosten verursachen. Um Missbrauch zu verhindern, muss sie mit einer anderen Phase (z. B.collection()) kombiniert werden, die durch Regeln überprüft werden kann.
Phasen der Feldänderung
Regeln gelten nur für gespeicherte Daten und nicht für abgeleitete Werte. Wenn eine Pipeline Phasen enthält, in denen Felder geändert werden (z. B. add_fields(...), replace_with(...), select(...), remove_fields(...)), wendet die Regel-Engine nach dieser Phase keine Filtereinschränkungen mehr an. Damit die Regeln wie erwartet funktionieren, positionieren Sie die Filterphasen (z.B. where) vor allen Phasen, in denen die ursprünglich gespeicherten Dokumente geändert werden können.
Ein Beispiel ist die folgende Sicherheitsregel:
match /databases/{database}/documents {
match /cities/{city} {
// Allow the user to read data if the document has the 'visibility'
// field set to 'public'
allow read: if resource.data.visibility == 'public';
}
}
Abgelehnt: Diese Regel lehnt die folgende Pipeline ab, da die Phase addFields vor dem Filtern nach Dokumenten erfolgt, bei denen visibility den Wert public hat:
const results = await db.pipeline()
.collection("/cities")
// Filters after a modification stage are ignored by Rules.
.addFields(constant(1000).as("population"))
.where(eq(field("visibility"), constant("public")))
.execute();
Zulässig: Diese Regel lässt die folgende Pipeline zu, da die Phase where(eq(field("visibility"), constant("public"))) vor allen Änderungsphasen auftritt:
const results = await db.pipeline()
.collection("/cities")
.where(eq(field("visibility"), constant("public")))
.addFields(constant(1000).as("population"))
.execute();
Phasen der Datenbearbeitungssprache und Sicherheitsregeln
Beim Ausführen von Phasen der Datenbearbeitungssprache (Data Manipulation Language, DML) (insert(), update(), upsert() und delete()) werden Berechtigungen von Sicherheitsregeln anders bewertet als bei Leseabfragen:
- Regelbewertung pro Dokument: Im Gegensatz zu Lesepipelines, für die Filterausdrücke im Voraus erforderlich sind, um die Abfrage bei der Planung einzuschränken, werden bei DML-Vorgängen Sicherheitsregeln für jede einzelne Dokumentänderung ausgewertet.
- Regelvariablen:
request.resource: Enthält die vorgeschlagenen Dokumentdaten für die Vorgängeinsert(),update()undupsert().resource: Enthält die aktuellen Dokumentdaten, die vor der Änderung im Datenspeicher gespeichert wurden (verfügbar fürupdate(),delete()undupsert()vorhandener Dokumente).
Systemlimits und Ausführungsverhalten mit DML
Beachten Sie beim Ausführen von DML-Vorgängen mit Sicherheitsregeln die folgenden Systemlimits und Ausführungsverhaltensweisen:
Das Limit von 20 Suchanfragen für get() und exists()
Firebase-Sicherheitsregeln erlauben maximal 20 Dokumentabfragen (get() oder exists()) pro Anfrage.
Wenn eine DML-Pipeline außerhalb einer expliziten Transaktion ausgeführt wird, verarbeitet Cloud Firestore Dokumentschreibvorgänge in Batches. Da jeder Batch in einer eigenen Transaktion ausgeführt wird und Dokumente zwischen Batches gleichzeitig geändert werden können, werden Sicherheitsregeln und Dokumentabfragen für jeden Schreib-Batch neu ausgewertet.
Auch wenn Ihre Sicherheitsregeln anhand eines einzelnen statischen Dokuments ausgewertet werden (z. B. um zu prüfen, ob ein Nutzer ein Administrator ist):
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /posts/{postId} {
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.isAdmin == true;
}
}
}
Für jeden Schreib-Batch mit 10 Dokumenten wird eine Suche durchgeführt. Nachdem alle möglichen Dokumente geschrieben wurden, ist das Limit von 20 Suchvorgängen für die Anfrage erreicht und die Pipeline schlägt mit dem Fehler PERMISSION_DENIED fehl. Darüber hinaus wird jede Suche, die pro Schreib-Batch ausgeführt wird, separat abgerechnet.
Teilweise erfolgreich und PERMISSION_DENIED
Wenn DML-Vorgänge außerhalb einer Transaktion ausgeführt werden, werden Schreibvorgänge in sequenziellen Batches festgeschrieben. Wenn ein Batch fehlschlägt, weil ein Dokument eine Regelbedingung nicht erfüllt oder das Limit von 20 Suchvorgängen überschritten wird, wird die Pipeline angehalten und ein PERMISSION_DENIED-Fehler zurückgegeben.
Batches, die bereits festgeschrieben wurden, werden jedoch nicht zurückgesetzt. Die Datenbank bleibt in einem teilweise aktualisierten Zustand. Da der Client einen Fehler ohne eine Liste der geänderten Dokumente erhält, müssen Sie Ihre Daten abfragen, um zu prüfen, welche Schreibvorgänge erfolgreich waren.
Regelfehler mit Cloud-Audit-Logs diagnostizieren
Aus Sicherheitsgründen wird bei clientseitigen PERMISSION_DENIED-Fehlern nicht offengelegt, welche Sicherheitsregelbedingung fehlgeschlagen ist oder ob das Limit von 20 Suchvorgängen erreicht wurde.
Um Fehler bei der Regelauswertung zu diagnostizieren, können Projektadministratoren Cloud-Audit-Logs in der Google Cloud Console (unter Firestore > Monitoring oder im Log-Explorer) einsehen, um detaillierte EvaluationError-Einträge aufzurufen.