Catch up on everything we announced at this year's Firebase Summit. Learn more

Sprache der Sicherheitsregeln

Firebase-Sicherheitsregeln nutzen flexible, leistungsstarke, benutzerdefinierte Sprachen, die ein breites Spektrum an Komplexität und Granularität unterstützen. Sie können Ihre Regeln so spezifisch oder allgemein gestalten, wie es für Ihre App sinnvoll ist. Echtzeitdatenbankregeln verwenden eine Syntax, die wie JavaScript in einer JSON-Struktur aussieht. Cloud Firestor und Cloud Storage Regeln verwenden , um eine Sprache auf der Grundlage der gemeinsamen Expression Language (CEL) , die mit auf CEL baut match und allow Aussagen , dass die Unterstützung Zugang bedingt gewährt.

Da es sich jedoch um benutzerdefinierte Sprachen handelt, gibt es eine Lernkurve. Verwenden Sie diesen Leitfaden, um die Regelsprache besser zu verstehen, während Sie tiefer in komplexere Regeln eintauchen.

Wählen Sie ein Produkt aus, um mehr über seine Regeln zu erfahren.

Grundstruktur

Cloud Firestore

Firebase-Sicherheitsregeln in Cloud Firestore und Cloud Storage verwenden die folgende Struktur und Syntax:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

Es ist wichtig, die folgenden Schlüsselkonzepte beim Erstellen der Regeln zu verstehen:

  • Anforderung: Das Verfahren oder die aufgerufenen Methoden in der allow Aussage. Dies sind Methoden, die Sie ausführen dürfen. Die Standardmethoden sind: get , list , create , update und delete . Die read und write Methoden ermöglichen breite Lese- und Schreibzugriff auf die angegebene Datenbank oder Speicherpfad.
  • Pfad: Die Datenbank oder Speicherort, als URI - Pfad dargestellt.
  • Regel: Die allow Anweisung, die eine Bedingung enthält , die eine Anforderung erlaubt , wenn es true ergibt.

Jedes dieser Konzepte wird unten ausführlicher beschrieben.

Cloud-Speicher

Firebase-Sicherheitsregeln in Cloud Firestore und Cloud Storage verwenden die folgende Struktur und Syntax:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

Es ist wichtig, die folgenden Schlüsselkonzepte zu verstehen, wenn Sie die Regeln erstellen:

  • Anforderung: Das Verfahren oder die aufgerufenen Methoden in der allow Aussage. Dies sind Methoden, die Sie ausführen dürfen. Die Standardmethoden sind: get , list , create , update und delete . Die read und write Methoden ermöglichen breite Lese- und Schreibzugriff auf die angegebene Datenbank oder Speicherpfad.
  • Pfad: Die Datenbank oder Speicherort, als URI - Pfad dargestellt.
  • Regel: Die allow Anweisung, die eine Bedingung enthält , die eine Anforderung erlaubt , wenn es true ergibt.

Jedes dieser Konzepte wird unten ausführlicher beschrieben.

Echtzeit-Datenbank

In Realtime Database bestehen Firebase-Sicherheitsregeln aus JavaScript-ähnlichen Ausdrücken, die in einem JSON-Dokument enthalten sind.

Sie verwenden die folgende Syntax:

{
  "rules": {
    "<<path>>": {
    // Allow the request if the condition for each method is true.
      ".read": <<condition>>,
      ".write": <<condition>>,
      ".validate": <<condition>>
    }
  }
}

Es gibt drei grundlegende Elemente in der Regel:

  • Pfad: Der Speicherort der Datenbank. Dies spiegelt die JSON-Struktur Ihrer Datenbank wider.
  • Anfrage: Dies sind die Methoden der Regel Anwendungen Zugriff zu gewähren. Die read und write gewähren breite Lese- und Schreibzugriff, während validate Regeln als sekundäre Überprüfung zur Gewährung des Zugangs handeln basierend auf eingehenden oder bestehende Daten.
  • Zustand: Der Zustand, der eine Anforderung erlaubt , wenn es true ergibt.

Regelkonstrukte

Cloud Firestore

Die grundlegenden Elemente einer Regel in Cloud Firestore und Cloud Storage lauten wie folgt:

  • Die service - Erklärung: Deklariert die Firebase Produkt der Regeln anzuwenden.
  • Das match Block: Definiert einen Pfad in der Datenbank oder Speicher Eimer die Regeln anzuwenden.
  • Die allow Erklärung: Stellt Bedingungen für die Gewährung des Zugangs, durch Methoden unterschieden. Die unterstützten Methoden umfassen: get , list , create , update , delete und die Bequemlichkeit Methoden read und write .
  • Optional function Erklärungen: Geben Sie die Möglichkeit , zu kombinieren und wickeln Bedingungen für den Einsatz über mehrere Regeln.

Der service enthält ein oder mehr match - Blöcke mit allow Aussagen , die Bedingungen der Gewährung des Zugangs zu Anfragen zur Verfügung stellen. Die request und resource sind für den Einsatz in Regelbedingungen zur Verfügung. Die Firebase Sicherheitsregeln Sprache unterstützt auch function

Syntaxversion

Die syntax - Anweisung gibt die Version der Firebase Regeln Sprache verwendet , um die Quelle zu schreiben. Die neueste Version der Sprache ist v2 .

rules_version = '2';
service cloud.firestore {
...
}

Wenn keine rules_version Erklärung geliefert wird, werden Ihre Regeln ausgewertet , um die Verwendung von v1 Motor.

Service

Die service - Erklärung definiert , welche Firebase Produkt oder eine Dienstleistung, Ihre Regeln anzuwenden. Sie können nur einen umfassen service Erklärung pro Quelldatei.

Cloud Firestore

service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}

Cloud-Speicher

service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

Wenn Sie Regeln für Cloud Firestore und Cloud Storage mit der Firebase-CLI definieren, müssen Sie diese in separaten Dateien verwalten.

Spiel

Ein match Block deklariert einen path , das gegenüber dem Pfad für die angeforderte Operation abgestimmt ist (die ankommende request.path ). Der Körper des match muss eine oder mehrere verschachtelte haben match Blöcke, allow Aussagen oder function Der Pfad in verschachteltem match Blöcken auf den Pfad in dem übergeordneten relatives match Block.

Der path Muster ist ein Verzeichnis-wie Name, Variablen oder Platzhalter enthalten kann. Der path Muster ermöglicht Single-Pfad - Segment und Multi-Pfad - Segment Streichhölzer. Alle Variablen gebunden in einem path sind im match Umfang oder einem verschachtelten Bereich , wo der path deklariert wird.

Spiele gegen einen path Muster können teilweise oder vollständig sein:

  • Teilweise Übereinstimmung: Der path Muster ist ein Präfix-Match des request.path .
  • Vollständige Spiele: Der path Muster passt die gesamte request.path .

Wenn eine vollständige Übereinstimmung der Regeln innerhalb des Blocks vorgenommen wird ausgewertet. Wenn eine teilweise Übereinstimmung der verschachtelten gemacht match Regeln getestet , um zu sehen , ob ein verschachtelter path , das Spiel beenden,.

Die Regeln in jeder vollständigen match ausgewertet , um zu bestimmen , ob die Anforderung zu ermöglichen. Wenn eine übereinstimmende Regel den Zugriff gewährt, wird die Anforderung zugelassen. Wenn keine übereinstimmende Regel den Zugriff gewährt, wird die Anfrage abgelehnt.

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

Wie das obige Beispiel zeigt, sind die path unterstützt Erklärungen die folgenden Variablen:

  • Single-Segment Platzhalter: Ein Platzhaltervariable ist , durch Umwickeln eine Variable in geschweiften Klammern in einem Pfad erklärt: {variable} . Diese Variable ist innerhalb der match - Anweisung als string .
  • Recursive Platzhalter: Die rekursive oder Multisegment, Platzhalter entspricht mehrere Pfadsegmente auf oder unter einem Pfad. Dieser Platzhalter entspricht allen Pfaden unterhalb des von Ihnen festgelegten Speicherorts. Sie können es erklären durch die Zugabe =** String am Ende des Segments Variable: {variable=**} . Diese Variable ist innerhalb der match - Anweisung als path - Objekt.

Erlauben

Der match - Block enthält eine oder mehr allow Aussagen. Dies sind Ihre tatsächlichen Regeln. Sie können sie bewerben allow Regeln Methoden auf eine oder mehr. Die Bedingungen für eine allow Aussage wahr bewerten muß für Cloud Firestor oder Cloud Storage jede eingehende Anfrage zu gewähren. Sie können auch Schreib allow Aussagen ohne Bedingungen, zum Beispiel zu allow read . Wenn die allow Aussage keine Bedingung enthalten, aber es ermöglicht immer die Anforderung für diese Methode.

Wenn eine der allow Regeln für das Verfahren erfüllt sind, wird die Anfrage gestattet. Wenn eine umfassendere Regel den Zugriff gewährt, gewähren Regeln außerdem Zugriff und ignorieren alle detaillierteren Regeln, die den Zugriff einschränken könnten.

Betrachten Sie das folgende Beispiel, in dem jeder Benutzer seine eigenen Dateien lesen oder löschen kann. Eine genauere Regel lässt Schreibvorgänge nur zu, wenn der Benutzer, der den Schreibvorgang anfordert, Eigentümer der Datei ist und die Datei eine PNG-Datei ist. Ein Benutzer kann alle Dateien im Unterpfad löschen – auch wenn es sich nicht um PNGs handelt – weil die frühere Regel dies zulässt.

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}

Methode

Jede allow Anweisung enthält ein Verfahren , das den Zugriff auf eingehende Anfragen des gleichen Verfahrens gewährt.

Methode Art der Anfrage
Komfortmethoden
read Jede Art von Leseanfrage
write Jede Art von Schreibanfrage
Standardmethoden
get Leseanfragen für einzelne Dokumente oder Dateien
list Leseanfragen für Abfragen und Sammlungen
create Neue Dokumente oder Dateien schreiben
update In vorhandene Datenbankdokumente schreiben oder Dateimetadaten aktualisieren
delete Daten löschen

Sie können nicht überlappen Methoden in der gleichen lesen match Block oder widersprüchliche Schreibverfahren in der gleichen path Erklärung.

Die folgenden Regeln würden beispielsweise fehlschlagen:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}

Funktion

Wenn Ihre Sicherheitsregeln komplexer werden, möchten Sie möglicherweise Bedingungssätze in Funktionen einschließen, die Sie in Ihrem Regelsatz wiederverwenden können. Sicherheitsregeln unterstützen benutzerdefinierte Funktionen. Die Syntax für benutzerdefinierte Funktionen ähnelt ein wenig JavaScript, aber Sicherheitsregelfunktionen sind in einer domänenspezifischen Sprache geschrieben, die einige wichtige Einschränkungen aufweist:

  • Funktionen können nur eine einzige enthalten return - Anweisung. 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 sind. Zum Beispiel kann eine Funktion innerhalb des definierten service cloud.firestore Umfang hat Zugriff auf die resource Variable und integrierte Funktionen wie get() und exists() .
  • Funktionen können andere Funktionen aufrufen, aber nicht rekursiv sein. Die Gesamttiefe der Aufrufliste ist auf 20 begrenzt.
  • In Regeln Version v2 können Funktionen Variablen definieren die Verwendung von let - Schlüsselwort. Funktionen können bis zu 10 let-Bindungen haben, müssen jedoch mit einer return-Anweisung enden.

Eine Funktion wird mit dem definierten function Schlüsselwort und nimmt null oder mehr Argumente. Sie können beispielsweise 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();
    }
  }
}

Hier ist ein Beispiel, das Funktionsargumente und let-Zuweisungen zeigt. Zuweisungsanweisungen müssen durch Semikola getrennt werden.

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

Beachten Sie, wie die isAdmin Zuordnung einer Lookup der admins Sammlung erzwingt. Für lazy evaluation ohne unnötige Lookups zu erfordern, nutzen die Kurzschließen der Natur von && (AND) und || (OR) Vergleiche nur eine zweite Funktion zu nennen , wenn isAuthor gezeigt, um wahr zu sein ( && Vergleiche) oder falsch (für || Vergleiche).

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

Durch die Verwendung von Funktionen in Ihren Sicherheitsregeln werden diese mit zunehmender Komplexität Ihrer Regeln leichter wartbar.

Cloud-Speicher

Die grundlegenden Elemente einer Regel in Cloud Firestore und Cloud Storage lauten wie folgt:

  • Die service - Erklärung: Deklariert die Firebase Produkt der Regeln anzuwenden.
  • Das match Block: Definiert einen Pfad in der Datenbank oder Speicher Eimer die Regeln anzuwenden.
  • Die allow Erklärung: Stellt Bedingungen für die Gewährung des Zugangs, durch Methoden unterschieden. Die unterstützten Methoden umfassen: get , list , create , update , delete und die Bequemlichkeit Methoden read und write .
  • Optional function Erklärungen: Geben Sie die Möglichkeit , zu kombinieren und wickeln Bedingungen für den Einsatz über mehrere Regeln.

Der service enthält ein oder mehr match - Blöcke mit allow Aussagen , die Bedingungen der Gewährung des Zugangs zu Anfragen zur Verfügung stellen. Die request und resource sind für den Einsatz in Regelbedingungen zur Verfügung. Die Firebase Sicherheitsregeln Sprache unterstützt auch function

Syntaxversion

Die syntax - Anweisung gibt die Version der Firebase Regeln Sprache verwendet , um die Quelle zu schreiben. Die neueste Version der Sprache ist v2 .

rules_version = '2';
service cloud.firestore {
...
}

Wenn keine rules_version Erklärung geliefert wird, werden Ihre Regeln ausgewertet , um die Verwendung von v1 Motor.

Service

Die service - Erklärung definiert , welche Firebase Produkt oder eine Dienstleistung, Ihre Regeln anzuwenden. Sie können nur einen umfassen service Erklärung pro Quelldatei.

Cloud Firestore

service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}

Cloud-Speicher

service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

Wenn Sie Regeln für Cloud Firestore und Cloud Storage mit der Firebase-CLI definieren, müssen Sie diese in separaten Dateien verwalten.

Spiel

Ein match Block deklariert einen path , das gegenüber dem Pfad für die angeforderte Operation abgestimmt ist (die ankommende request.path ). Der Körper des match muss eine oder mehrere verschachtelte haben match Blöcke, allow Aussagen oder function Der Pfad in verschachteltem match Blöcken auf den Pfad in dem übergeordneten relatives match Block.

Der path Muster ist ein Verzeichnis-wie Name, Variablen oder Platzhalter enthalten kann. Der path Muster ermöglicht Single-Pfad - Segment und Multi-Pfad - Segment Streichhölzer. Alle Variablen gebunden in einem path sind im match Umfang oder einem verschachtelten Bereich , wo der path deklariert wird.

Spiele gegen einen path Muster können teilweise oder vollständig sein:

  • Teilweise Übereinstimmung: Der path Muster ist ein Präfix-Match des request.path .
  • Vollständige Spiele: Der path Muster passt die gesamte request.path .

Wenn eine vollständige Übereinstimmung der Regeln innerhalb des Blocks vorgenommen wird ausgewertet. Wenn eine teilweise Übereinstimmung der verschachtelten gemacht match Regeln getestet , um zu sehen , ob ein verschachtelter path , das Spiel beenden,.

Die Regeln in jeder vollständigen match ausgewertet , um zu bestimmen , ob die Anforderung zu ermöglichen. Wenn eine übereinstimmende Regel den Zugriff gewährt, wird die Anforderung zugelassen. Wenn keine übereinstimmende Regel den Zugriff gewährt, wird die Anfrage abgelehnt.

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

Wie das obige Beispiel zeigt, sind die path unterstützt Erklärungen die folgenden Variablen:

  • Single-Segment Platzhalter: Ein Platzhaltervariable ist , durch Umwickeln eine Variable in geschweiften Klammern in einem Pfad erklärt: {variable} . Diese Variable ist innerhalb der match - Anweisung als string .
  • Recursive Platzhalter: Die rekursive oder Multisegment, Platzhalter entspricht mehrere Pfadsegmente auf oder unter einem Pfad. Dieser Platzhalter entspricht allen Pfaden unterhalb des von Ihnen festgelegten Speicherorts. Sie können es erklären durch die Zugabe =** String am Ende des Segments Variable: {variable=**} . Diese Variable ist innerhalb der match - Anweisung als path - Objekt.

Erlauben

Der match - Block enthält eine oder mehr allow Aussagen. Dies sind Ihre tatsächlichen Regeln. Sie können sie bewerben allow Regeln Methoden auf eine oder mehr. Die Bedingungen für eine allow Aussage wahr bewerten muß für Cloud Firestor oder Cloud Storage jede eingehende Anfrage zu gewähren. Sie können auch Schreib allow Aussagen ohne Bedingungen, zum Beispiel zu allow read . Wenn die allow Aussage keine Bedingung enthalten, aber es ermöglicht immer die Anforderung für diese Methode.

Wenn eine der allow Regeln für das Verfahren erfüllt sind, wird die Anfrage gestattet. Wenn eine umfassendere Regel den Zugriff gewährt, gewähren Regeln außerdem Zugriff und ignorieren alle detaillierteren Regeln, die den Zugriff einschränken könnten.

Betrachten Sie das folgende Beispiel, in dem jeder Benutzer seine eigenen Dateien lesen oder löschen kann. Eine genauere Regel lässt Schreibvorgänge nur zu, wenn der Benutzer, der den Schreibvorgang anfordert, Eigentümer der Datei ist und die Datei eine PNG-Datei ist. Ein Benutzer kann alle Dateien im Unterpfad löschen – auch wenn es sich nicht um PNGs handelt – weil die frühere Regel dies zulässt.

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}

Methode

Jede allow Anweisung enthält ein Verfahren , das den Zugriff auf eingehende Anfragen des gleichen Verfahrens gewährt.

Methode Art der Anfrage
Komfortmethoden
read Jede Art von Leseanfrage
write Jede Art von Schreibanfrage
Standardmethoden
get Leseanfragen für einzelne Dokumente oder Dateien
list Leseanfragen für Abfragen und Sammlungen
create Neue Dokumente oder Dateien schreiben
update In vorhandene Datenbankdokumente schreiben oder Dateimetadaten aktualisieren
delete Daten löschen

Sie können nicht überlappen Methoden in der gleichen lesen match Block oder widersprüchliche Schreibverfahren in der gleichen path Erklärung.

Die folgenden Regeln würden beispielsweise fehlschlagen:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}

Funktion

Wenn Ihre Sicherheitsregeln komplexer werden, möchten Sie möglicherweise Bedingungssätze in Funktionen einschließen, die Sie in Ihrem Regelsatz wiederverwenden können. Sicherheitsregeln unterstützen benutzerdefinierte Funktionen. Die Syntax für benutzerdefinierte Funktionen ähnelt ein wenig JavaScript, aber Sicherheitsregelfunktionen sind in einer domänenspezifischen Sprache geschrieben, die einige wichtige Einschränkungen aufweist:

  • Funktionen können nur eine einzige enthalten return - Anweisung. 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 sind. Zum Beispiel kann eine Funktion innerhalb des definierten service cloud.firestore Umfang hat Zugriff auf die resource Variable und integrierte Funktionen wie get() und exists() .
  • Funktionen können andere Funktionen aufrufen, aber nicht rekursiv sein. Die Gesamttiefe der Aufrufliste ist auf 20 begrenzt.
  • In Regeln Version v2 können Funktionen Variablen definieren die Verwendung von let - Schlüsselwort. Funktionen können bis zu 10 let-Bindungen haben, müssen jedoch mit einer return-Anweisung enden.

Eine Funktion wird mit dem definierten function Schlüsselwort und nimmt null oder mehr Argumente. Sie können beispielsweise 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();
    }
  }
}

Hier ist ein Beispiel, das Funktionsargumente und let-Zuweisungen zeigt. Let-Zuweisungsanweisungen müssen durch Semikola getrennt werden.

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

Beachten Sie, wie die isAdmin Zuordnung einer Lookup der admins Sammlung erzwingt. Für lazy evaluation ohne unnötige Lookups zu erfordern, nutzen die Kurzschließen der Natur von && (AND) und || (OR) Vergleiche nur eine zweite Funktion zu nennen , wenn isAuthor gezeigt, um wahr zu sein ( && Vergleiche) oder falsch (für || Vergleiche).

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

Durch die Verwendung von Funktionen in Ihren Sicherheitsregeln werden diese mit zunehmender Komplexität Ihrer Regeln leichter wartbar.

Echtzeit-Datenbank

Wie oben beschrieben umfassen Echtzeit-Datenbankregeln drei grundlegende Elemente: den Datenbankspeicherort als Spiegel der JSON-Struktur der Datenbank, den Anforderungstyp und die Bedingung, die den Zugriff gewährt.

Speicherort der Datenbank

Die Struktur Ihrer Regeln sollte der Struktur der Daten entsprechen, die Sie in Ihrer Datenbank gespeichert haben. In einer Chat-App mit einer Liste von Nachrichten können Sie beispielsweise Daten haben, die wie folgt aussehen:

  {
    "messages": {
      "message0": {
        "content": "Hello",
        "timestamp": 1405704370369
      },
      "message1": {
        "content": "Goodbye",
        "timestamp": 1405704395231
      },
      ...
    }
  }

Ihre Regeln sollten diese Struktur widerspiegeln. Zum Beispiel:

  {
    "rules": {
      "messages": {
        "$message": {
          // only messages from the last ten minutes can be read
          ".read": "data.child('timestamp').val() > (now - 600000)",

          // new messages must have a string content and a number timestamp
          ".validate": "newData.hasChildren(['content', 'timestamp']) &&
                        newData.child('content').isString() &&
                        newData.child('timestamp').isNumber()"
        }
      }
    }
  }

Wie das Beispiel zeigt, stützen Realtime Datenbank - Regeln eine $location variable Pfadsegmente entsprechen. Verwenden Sie den $ Präfix vor dem Pfadsegment der Regel auf alle untergeordneten Knoten auf dem Weg zu entsprechen.

  {
    "rules": {
      "rooms": {
        // This rule applies to any child of /rooms/, the key for each room id
        // is stored inside $room_id variable for reference
        "$room_id": {
          "topic": {
            // The room's topic can be changed if the room id has "public" in it
            ".write": "$room_id.contains('public')"
          }
        }
      }
    }
  }

Sie können auch die Verwendung $variable parallel zu konstanten Pfadnamen.

  {
    "rules": {
      "widget": {
        // a widget can have a title or color attribute
        "title": { ".validate": true },
        "color": { ".validate": true },

        // but no other child paths are allowed
        // in this case, $other means any key excluding "title" and "color"
        "$other": { ".validate": false }
      }
    }
  }

Methode

In der Echtzeitdatenbank gibt es drei Arten von Regeln. Zwei dieser Regeltypen - read und write - gelten für das Verfahren einer eingehenden Anfrage. Der validate - Regeltyp erzwingt Datenstrukturen und validiert das Format und den Inhalt der Daten. Regeln laufen .validate Regeln nach der Überprüfung , dass ein .write Regel Zugang gewährt.

Regeltypen
.lesen Beschreibt, ob und wann Daten von Benutzern gelesen werden dürfen.
.schreiben Beschreibt, ob und wann Daten geschrieben werden dürfen.
.bestätigen Definiert, wie ein korrekt formatierter Wert aussieht, ob er untergeordnete Attribute hat und den Datentyp.

Wenn es keine Regel gibt, die dies zulässt, wird der Zugriff auf einen Pfad standardmäßig verweigert.

Baubedingungen

Cloud Firestore

Eine Bedingung ist ein boolescher Ausdruck, der bestimmt, ob eine bestimmte Operation zugelassen oder abgelehnt werden soll. Die request und resource liefern Kontext für diese Bedingungen.

Die request variable

Der request enthält die folgenden Felder und entsprechende Informationen:

request.auth

Ein JSON Web Token (JWT), das Authentifizierungsdaten von Firebase Authentication enthält. auth - Token enthält eine Reihe von Standard - Ansprüche und alle benutzerdefinierten Ansprüche Sie durch Firebase - Authentifizierung erstellen. Erfahren Sie mehr über Firebase Sicherheit Regeln und Authentifizierung .

request.method

Die request.method kann jedes der Standardverfahren oder eine benutzerdefinierte Methode. Die Bequemlichkeit Methoden read und write gibt es auch Regeln zu vereinfachen das Schreiben , die jeweils für alle schreibgeschützte oder alle Schreib nur Standardmethoden anzuwenden.

request.params

Die request.params umfassen alle Daten nicht speziell auf die im Zusammenhang request.resource , die für die Bewertung nützlich sein könnten. In der Praxis sollte diese Zuordnung für alle Standardmethoden leer sein und für benutzerdefinierte Methoden Nicht-Ressourcendaten enthalten. Dienste müssen darauf achten, den Typ von Schlüsseln und Werten, die als Parameter dargestellt werden, nicht umzubenennen oder zu ändern.

request.path

Der request.path ist der Pfad für die resource . Der Pfad ist relativ zum Dienst. Pfadsegmente nicht-url sichere Zeichen enthalten , wie zum Beispiel / sind URL-codiert.

Die resource variable

Die resource ist der aktuelle Wert innerhalb des Dienstes als eine Karte von Schlüssel-Wert - Paaren , dargestellt. Referenzierung resource innerhalb einer Bedingung führt in höchstens einen von dem Wert aus dem Dienst zu lesen. Diese Suche wird auf alle dienstbezogenen Kontingente für die Ressource angerechnet. Für get - Anfragen, die resource wird nur in Richtung Quote angerechnet auf verweigern.

Operatoren und Operator-Priorität

Verwenden Sie die folgende Tabelle als Referenz für Operatoren und deren entsprechende Rangfolge in den Regeln für Cloud Firestore und Cloud Storage.

Gegeben beliebige Ausdrücke a und b , ein Feld f und einen Index i .

Operator Beschreibung Assoziativität
a[i] a() af Index, Aufruf, Feldzugriff links nach rechts
!a -a Unäre Negation rechts nach links
a/ba%ba*b Multiplikative Operatoren links nach rechts
a+b ab Additive Operatoren links nach rechts
a>ba>=ba Relationale Operatoren links nach rechts
a in b Existenz in Liste oder Karte links nach rechts
a is type Typenvergleich, in dem type Bool sein kann, int, float, Zahl, ein String - Liste, Karte, Zeitstempel, Dauer, Pfad oder latlng links nach rechts
a==ba!=b Vergleichsoperatoren links nach rechts
a && b Bedingtes UND links nach rechts
a || b Bedingtes ODER links nach rechts
a ? true_value : false_value Ternärer Ausdruck links nach rechts

Cloud-Speicher

Eine Bedingung ist ein boolescher Ausdruck, der bestimmt, ob eine bestimmte Operation zugelassen oder abgelehnt werden soll. Die request und resource liefern Kontext für diese Bedingungen.

Die request variable

Der request enthält die folgenden Felder und entsprechende Informationen:

request.auth

Ein JSON Web Token (JWT), das Authentifizierungsdaten von Firebase Authentication enthält. auth - Token enthält eine Reihe von Standard - Ansprüche und alle benutzerdefinierten Ansprüche Sie durch Firebase - Authentifizierung erstellen. Erfahren Sie mehr über Firebase Sicherheit Regeln und Authentifizierung .

request.method

Die request.method kann jedes der Standardverfahren oder eine benutzerdefinierte Methode. Die Bequemlichkeit Methoden read und write gibt es auch Regeln zu vereinfachen das Schreiben , die jeweils für alle schreibgeschützte oder alle Schreib nur Standardmethoden anzuwenden.

request.params

Die request.params umfassen alle Daten nicht speziell auf die im Zusammenhang request.resource , die für die Bewertung nützlich sein könnten. In der Praxis sollte diese Zuordnung für alle Standardmethoden leer sein und für benutzerdefinierte Methoden Nicht-Ressourcendaten enthalten. Dienste müssen darauf achten, den Typ von Schlüsseln und Werten, die als Parameter dargestellt werden, nicht umzubenennen oder zu ändern.

request.path

Der request.path ist der Pfad für die resource . Der Pfad ist relativ zum Dienst. Pfadsegmente nicht-url sichere Zeichen enthalten , wie zum Beispiel / sind URL-codiert.

Die resource variable

Die resource ist der aktuelle Wert innerhalb des Dienstes als eine Karte von Schlüssel-Wert - Paaren , dargestellt. Referenzierung resource innerhalb einer Bedingung führt in höchstens einen von dem Wert aus dem Dienst zu lesen. Diese Suche wird auf alle dienstbezogenen Kontingente für die Ressource angerechnet. Für get - Anfragen, die resource wird nur in Richtung Quote angerechnet auf verweigern.

Operatoren und Operator-Priorität

Verwenden Sie die folgende Tabelle als Referenz für Operatoren und deren entsprechende Rangfolge in den Regeln für Cloud Firestore und Cloud Storage.

Gegeben beliebige Ausdrücke a und b , ein Feld f und einen Index i .

Operator Beschreibung Assoziativität
a[i] a() af Index, Aufruf, Feldzugriff links nach rechts
!a -a Unäre Negation rechts nach links
a/ba%ba*b Multiplikative Operatoren links nach rechts
a+b ab Additive Operatoren links nach rechts
a>ba>=ba Relationale Operatoren links nach rechts
a in b Existenz in Liste oder Karte links nach rechts
a is type Typenvergleich, in dem type Bool sein kann, int, float, Zahl, ein String - Liste, Karte, Zeitstempel, Dauer, Pfad oder latlng links nach rechts
a==ba!=b Vergleichsoperatoren links nach rechts
a && b Bedingtes UND links nach rechts
a || b Bedingtes ODER links nach rechts
a ? true_value : false_value Ternärer Ausdruck links nach rechts

Echtzeit-Datenbank

Eine Bedingung ist ein boolescher Ausdruck, der bestimmt, ob eine bestimmte Operation zugelassen oder abgelehnt werden soll. Sie können diese Bedingungen in Echtzeit-Datenbankregeln wie folgt definieren.

Vordefinierte Variablen

Es gibt eine Reihe hilfreicher vordefinierter Variablen, auf die innerhalb einer Regeldefinition zugegriffen werden kann. Hier ist jeweils eine kurze Zusammenfassung:

Vordefinierte Variablen
jetzt Die aktuelle Zeit in Millisekunden seit der Linux-Epoche. Dies funktioniert besonders gut für die Validierung von Zeitstempeln, die mit firebase.database.ServerValue.TIMESTAMP des SDK erstellt wurden.
Wurzel Ein RuleDataSnapshot des Root - Pfad in der Datenbank Firebase darstellt , wie es vor der versuchten Operation besteht.
neue Daten A RuleDataSnapshot , die die Daten , wie sie nach der versuchten Operation existieren würden. Es enthält die neu geschriebenen Daten und die vorhandenen Daten.
Daten A RuleDataSnapshot , die die Daten , wie sie vor der versuchten Operation vorlag.
$-Variablen Ein Platzhalterpfad, der verwendet wird, um IDs und dynamische untergeordnete Schlüssel darzustellen.
auth Stellt die Tokennutzlast eines authentifizierten Benutzers dar.

Diese Variablen können überall in Ihren Regeln verwendet werden. Zum Beispiel sorgen die Sicherheitsregeln unterhalb dieser Daten geschrieben das /foo/ Knoten muss eine Zeichenfolge weniger als 100 Zeichen:

{
  "rules": {
    "foo": {
      // /foo is readable by the world
      ".read": true,

      // /foo is writable by the world
      ".write": true,

      // data written to /foo must be a string less than 100 characters
      ".validate": "newData.isString() && newData.val().length < 100"
    }
  }
}

Datenbasierte Regeln

Alle Daten in Ihrer Datenbank können in Ihren Regeln verwendet werden. Mit Hilfe der vordefinierten Variablen root , data und newData können Sie einen beliebigen Pfad zugreifen , wie es vor oder nach einem Schreibereignis existieren würde.

Betrachten Sie dieses Beispiel, die Schreiboperationen , solange der Wert des erlaubt /allow_writes/ Knoten ist true , der übergeordnete Knoten ein nicht haben readOnly - Flag gesetzt, und es gibt ein Kind namens foo in den neu geschriebenen Daten:

".write": "root.child('allow_writes').val() === true &&
          !data.parent().child('readOnly').exists() &&
          newData.child('foo').exists()"

Abfragebasierte Regeln

Obwohl Sie Regeln nicht als Filter verwenden können, können Sie den Zugriff auf Teilmengen von Daten einschränken, indem Sie Abfrageparameter in Ihren Regeln verwenden. Verwenden Sie query. Ausdrücke in Ihren Regeln, um Lese- oder Schreibzugriff basierend auf Abfrageparametern zu gewähren.

Zum Beispiel verwendet die folgende abfragebasierte Regel benutzerbasierte Sicherheitsregeln und abfragebasierte Regeln Zugriff auf die Daten in der beschränken baskets Sammlung nur auf die Einkaufskörbe der aktive Benutzer besitzt:

"baskets": {
  ".read": "auth.uid != null &&
            query.orderByChild == 'owner' &&
            query.equalTo == auth.uid" // restrict basket access to owner of basket
}

Die folgende Abfrage, die die Abfrageparameter in der Regel enthält, wäre erfolgreich:

db.ref("baskets").orderByChild("owner")
                 .equalTo(auth.currentUser.uid)
                 .on("value", cb)                 // Would succeed

Allerdings Abfragen , die mit einem nicht über die Parameter in der Regel umfassen würde scheitern PermissionDenied Fehler:

db.ref("baskets").on("value", cb)                 // Would fail with PermissionDenied

Sie können auch abfragebasierte Regeln verwenden, um zu begrenzen, wie viele Daten ein Client durch Lesevorgänge herunterlädt.

Die folgende Regel beschränkt beispielsweise den Lesezugriff auf die ersten 1000 Ergebnisse einer Abfrage, sortiert nach Priorität:

messages: {
  ".read": "query.orderByKey &&
            query.limitToFirst <= 1000"
}

// Example queries:

db.ref("messages").on("value", cb)                // Would fail with PermissionDenied

db.ref("messages").limitToFirst(1000)
                  .on("value", cb)                // Would succeed (default order by key)

Die folgende query. Ausdrücke sind in Echtzeit-Datenbankregeln verfügbar.

Abfragebasierte Regelausdrücke
Ausdruck Typ Beschreibung
query.orderByKey
query.orderByPriority
query.orderByValue
boolesch True für Abfragen, die nach Schlüssel, Priorität oder Wert geordnet sind. Sonst falsch.
query.orderByChild Schnur
Null
Verwenden Sie eine Zeichenfolge, um den relativen Pfad zu einem untergeordneten Knoten darzustellen. Zum Beispiel query.orderByChild == "address/zip" . Wenn die Abfrage nicht nach einem untergeordneten Knoten sortiert ist, ist dieser Wert null.
query.startAt
query.endAt
query.equalTo
Schnur
Nummer
boolesch
Null
Ruft die Grenzen der ausgeführten Abfrage ab oder gibt null zurück, wenn kein gebundener Satz vorhanden ist.
query.limitToFirst
query.limitToLast
Nummer
Null
Ruft das Limit für die ausgeführte Abfrage ab oder gibt null zurück, wenn kein Limit festgelegt ist.

Betreiber

Realtime Datenbank - Regeln unterstützen eine Reihe von Operatoren können Sie Variablen in der Bedingungsanweisung kombinieren verwenden. Die vollständige Liste der Operatoren in der Referenzdokumentation .

Bedingungen schaffen

Ihre tatsächlichen Bedingungen variieren je nach dem Zugriff, den Sie gewähren möchten. Regeln bieten absichtlich ein enormes Maß an Flexibilität, sodass die Regeln Ihrer App letztendlich so einfach oder komplex sein können, wie Sie es benötigen.

Für einige Hinweise der Erstellung von einfachen, produktionsfertige Regeln finden Grundlegende Sicherheitsregeln .