Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Langue des règles de sécurité

Les règles de sécurité Firebase s'appuient sur des langages flexibles, puissants et personnalisés qui prennent en charge un large éventail de complexité et de granularité. Vous pouvez rendre vos règles aussi spécifiques ou aussi générales que logique pour votre application. Les règles de base de données en temps réel utilisent une syntaxe qui ressemble à JavaScript dans une structure JSON. Cloud FireStore et Cloud règles de stockage utilisent un langage basé sur l' expression Common Language (CEL) , qui se base sur CEL avec match et allow des déclarations que le soutien accordé l' accès conditionnel.

Comme il s'agit de langages personnalisés, il existe cependant une courbe d'apprentissage. Utilisez ce guide pour mieux comprendre le langage des règles tout en approfondissant des règles plus complexes.

Sélectionnez un produit pour en savoir plus sur ses règles.

Structure basique

Cloud Firestore

Les règles de sécurité Firebase dans Cloud Firestore et Cloud Storage utilisent la structure et la syntaxe suivantes :

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

Les concepts clés suivants sont importants à comprendre lorsque vous créez les règles :

  • Demande: La méthode ou les méthodes invoquées dans la allow déclaration. Ce sont des méthodes que vous autorisez à exécuter. Les méthodes standard sont: get , list , create , update à delete update et delete . Les read et write méthodes pratiques permettent un large accès de lecture et d' écriture sur la base de données ou d'une trajectoire de stockage.
  • Path: L'emplacement de base de données ou de stockage, représentée comme un chemin d' accès d' URI.
  • Règle: La allow déclaration, qui comprend une condition qui permet une demande si elle est évaluée à true.

Chacun de ces concepts est décrit plus en détail ci-dessous.

Stockage en ligne

Les règles de sécurité Firebase dans Cloud Firestore et Cloud Storage utilisent la structure et la syntaxe suivantes :

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

Les concepts clés suivants sont importants à comprendre lorsque vous créez les règles :

  • Demande: La méthode ou les méthodes invoquées dans la allow déclaration. Ce sont des méthodes que vous autorisez à exécuter. Les méthodes standard sont: get , list , create , update à delete update et delete . Les read et write méthodes pratiques permettent un large accès de lecture et d' écriture sur la base de données ou d'une trajectoire de stockage.
  • Path: L'emplacement de base de données ou de stockage, représentée comme un chemin d' accès d' URI.
  • Règle: La allow déclaration, qui comprend une condition qui permet une demande si elle est évaluée à true.

Chacun de ces concepts est décrit plus en détail ci-dessous.

Base de données en temps réel

Dans Realtime Database, les règles de sécurité Firebase se composent d'expressions de type JavaScript contenues dans un document JSON.

Ils utilisent la syntaxe suivante :

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

Il y a trois éléments de base dans la règle :

  • Chemin: L'emplacement de la base de données. Cela reflète la structure JSON de votre base de données.
  • Demande: Ce sont les méthodes les utilisations des règles pour accorder l' accès. Les read et write des règles accordent une large lecture et l' accès en écriture, alors que validate règles agissent comme vérification secondaire à l' accès aux subventions en fonction des données entrantes ou existantes.
  • Condition: La condition qui permet une demande si elle est évaluée à true.

Constructions de règles

Cloud Firestore

Les éléments de base d'une règle dans Cloud Firestore et Cloud Storage sont les suivants :

  • Le service de déclaration: Déclare le produit Firebase les règles applicables à.
  • Le match de bloc: définit un chemin dans le seau de base de données ou de stockage les règles applicables à.
  • La allow déclaration: Fournit les conditions d'octroi de l' accès, différenciés par des méthodes. Les méthodes prises en charge comprennent: get , list , create , update à delete read write update , delete , et les méthodes de commodité read et write .
  • Facultatif function déclarations: Fournir la possibilité de combiner et envelopper les conditions d'utilisation sur plusieurs règles.

Le service de contient un ou plusieurs match blocs avec allow des déclarations qui offrent des conditions donnant accès aux demandes. La request et les resource variables sont disponibles pour une utilisation dans des conditions de règle. Le langage Règles de sécurité Firebase prend également en charge la function déclarations.

Version de la syntaxe

La syntax déclaration indique la version de la langue Règles Firebase utilisé pour écrire la source. La dernière version de la langue est v2 .

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

Si aucune rules_version déclaration est fournie, vos règles seront évaluées en utilisant le v1 moteur.

Service

Les service déclaration définit quel produit Firebase ou service, vos règles s'appliquent. Vous ne pouvez inclure un service de déclaration par fichier source.

Cloud Firestore

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

Stockage en ligne

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

Si vous définissez des règles pour Cloud Firestore et Cloud Storage à l'aide de la CLI Firebase, vous devrez les conserver dans des fichiers séparés.

Rencontre

Une match bloc déclare un path motif qui est en correspondance avec le chemin d' accès pour l'opération demandée (le entrant request.path ). Le corps du match doit avoir un ou plusieurs imbriqués match des blocs, allow des déclarations, ou la function des déclarations. Le chemin en imbriqués match des blocs est par rapport à la trajectoire dans le parent match bloc.

Le path pattern est un nom comme répertoire qui peuvent inclure des variables ou des caractères génériques. Le path motif permet de segmenter un seul chemin et les matches de segments de trajets multiples. Toutes les variables liées dans un path sont visibles dans la match portée ou une portée imbriquée où le path est déclarée.

Matches contre un path modèle peut être partielle ou complète:

  • Les correspondances partielles: Le path modèle est un préfixe match de la request.path .
  • Complete matches: Le path modèle correspond à l'ensemble request.path .

Lorsqu'une correspondance complète est fait les règles au sein du bloc sont évaluées. Quand est fait les emboîtées une correspondance partielle match règles sont testées pour voir si tout imbriqué path complètera le match.

Les règles de chaque complète match sont évaluées pour déterminer si pour permettre la demande. Si une règle de correspondance accorde l'accès, la demande est autorisée. Si aucune règle de correspondance n'accorde l'accès, la demande est refusée.

// 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.
  }
}

Comme l'exemple ci - dessus montre, les path déclarations prend en charge les variables suivantes:

  • Joker-segment unique: Une variable générique est déclaré dans un trajet en enveloppant une variable entre accolades: {variable} . Cette variable est accessible dans le match de déclaration comme une string .
  • Génériques récursive: Le récursifs, ou multi-segments, les segments apparaissent génériques à trajets multiples au niveau ou en dessous d' un chemin d' accès. Ce caractère générique correspond à tous les chemins situés sous l'emplacement auquel vous l'avez défini. Vous pouvez le déclarer en ajoutant la =** chaîne à la fin de votre variable segment: {variable=**} . Cette variable est accessible dans le match de déclaration comme path objet.

Permettre

Le match de bloc contient un ou plusieurs allow des déclarations. Ce sont vos règles réelles. Vous pouvez appliquer allow des règles à une ou plusieurs méthodes. Les conditions sur une allow déclaration doit évaluer true pour Cloud Firestore ou Cloud Storage d'accorder toute demande entrante. Vous pouvez également écrire allow des déclarations sans conditions, par exemple, allow read de allow read . Si le allow cependant, il permet toujours la déclaration ne comprend pas une condition, la demande de cette méthode.

Si l' un des allow les règles de la méthode sont remplies, la demande est autorisée. De plus, si une règle plus large accorde l'accès, les règles accordent l'accès et ignorent les règles plus granulaires qui pourraient limiter l'accès.

Considérez l'exemple suivant, où n'importe quel utilisateur peut lire ou supprimer n'importe lequel de ses propres fichiers. Une règle plus précise n'autorise les écritures que si l'utilisateur qui demande l'écriture possède le fichier et que le fichier est au format PNG. Un utilisateur peut supprimer tous les fichiers du sous-chemin, même s'il ne s'agit pas de fichiers PNG, car la règle précédente le permet.

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

Méthode

Chaque allow déclaration comprend une méthode qui donne accès pour les requêtes entrantes de la même méthode.

Méthode Type de demande
Méthodes pratiques
read Tout type de demande de lecture
write Tout type de demande d'écriture
Méthodes standard
get Lire les demandes de documents ou de fichiers uniques
list Lire les demandes de requêtes et de collectes
create Écrire de nouveaux documents ou fichiers
update Écrire dans des documents de base de données existants ou mettre à jour les métadonnées du fichier
delete Suprimmer les données

Vous ne pouvez pas lire le chevauchement des méthodes dans la même match bloc ou méthodes d'écriture contradictoires dans la même path déclaration.

Par exemple, les règles suivantes échoueraient :

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

Fonction

Au fur et à mesure que vos règles de sécurité deviennent plus complexes, vous souhaiterez peut-être encapsuler des ensembles de conditions dans des fonctions que vous pourrez réutiliser dans votre ensemble de règles. Les règles de sécurité prennent en charge les fonctions personnalisées. La syntaxe des fonctions personnalisées ressemble un peu à JavaScript, mais les fonctions de règles de sécurité sont écrites dans un langage spécifique à un domaine qui présente des limitations importantes :

  • Les fonctions peuvent contenir qu'un seul return déclaration. Ils ne peuvent pas contenir de logique supplémentaire. Par exemple, ils ne peuvent pas exécuter de boucles ou appeler des services externes.
  • Les fonctions peuvent accéder automatiquement aux fonctions et variables à partir de la portée dans laquelle elles sont définies. Par exemple, une fonction définie dans le service cloud.firestore portée a accès à la resource variable et des fonctions intégrées telles que get() et exists() .
  • Les fonctions peuvent appeler d'autres fonctions mais ne peuvent pas se reproduire. La profondeur totale de la pile d'appels est limitée à 20.
  • Dans la version des règles v2 , les fonctions peuvent définir des variables à l' aide du let mot - clé. Les fonctions peuvent avoir jusqu'à 10 liaisons let, mais doivent se terminer par une instruction return.

Une fonction est définie par la function mot - clé et prend zéro ou plusieurs arguments. Par exemple, vous pouvez combiner les deux types de conditions utilisées dans les exemples ci-dessus en une seule fonction :

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

Voici un exemple montrant les arguments de fonction et les affectations let. Les instructions d'affectation Let doivent être séparées par des points-virgules.

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

Notez comment la isAdmin affectation applique une recherche de la collection admins. Pour l' évaluation paresseuse sans nécessiter des recherches inutiles, profiter de la nature à court-circuiter && (ET) et || (OR) pour appeler des comparaisons d' une deuxième fonction que si isAuthor se révèle être vrai (pour && comparaisons) ou faux (pour || comparaisons).

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

L'utilisation de fonctions dans vos règles de sécurité les rend plus faciles à gérer à mesure que la complexité de vos règles augmente.

Stockage en ligne

Les éléments de base d'une règle dans Cloud Firestore et Cloud Storage sont les suivants :

  • Le service de déclaration: Déclare le produit Firebase les règles applicables à.
  • Le match de bloc: définit un chemin dans le seau de base de données ou de stockage les règles applicables à.
  • La allow déclaration: Fournit les conditions d'octroi de l' accès, différenciés par des méthodes. Les méthodes prises en charge comprennent: get , list , create , update à delete read write update , delete , et les méthodes de commodité read et write .
  • Facultatif function déclarations: Fournir la possibilité de combiner et envelopper les conditions d'utilisation sur plusieurs règles.

Le service de contient un ou plusieurs match blocs avec allow des déclarations qui offrent des conditions donnant accès aux demandes. La request et les resource variables sont disponibles pour une utilisation dans des conditions de règle. Le langage Règles de sécurité Firebase prend également en charge la function déclarations.

Version de la syntaxe

La syntax déclaration indique la version de la langue Règles Firebase utilisé pour écrire la source. La dernière version de la langue est v2 .

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

Si aucune rules_version déclaration est fournie, vos règles seront évaluées en utilisant le v1 moteur.

Service

Les service déclaration définit quel produit Firebase ou service, vos règles s'appliquent. Vous ne pouvez inclure un service de déclaration par fichier source.

Cloud Firestore

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

Stockage en ligne

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

Si vous définissez des règles pour Cloud Firestore et Cloud Storage à l'aide de la CLI Firebase, vous devrez les conserver dans des fichiers séparés.

Rencontre

Une match bloc déclare un path motif qui est en correspondance avec le chemin d' accès pour l'opération demandée (le entrant request.path ). Le corps du match doit avoir un ou plusieurs imbriqués match des blocs, allow des déclarations, ou la function des déclarations. Le chemin en imbriqués match des blocs est par rapport à la trajectoire dans le parent match bloc.

Le path pattern est un nom comme répertoire qui peuvent inclure des variables ou des caractères génériques. Le path motif permet de segmenter un seul chemin et les matches de segments de trajets multiples. Toutes les variables liées dans un path sont visibles dans la match portée ou une portée imbriquée où le path est déclarée.

Matches contre un path modèle peut être partielle ou complète:

  • Les correspondances partielles: Le path modèle est un préfixe match de la request.path .
  • Complete matches: Le path modèle correspond à l'ensemble request.path .

Lorsqu'une correspondance complète est fait les règles au sein du bloc sont évaluées. Quand est fait les emboîtées une correspondance partielle match règles sont testées pour voir si tout imbriqué path complètera le match.

Les règles de chaque complète match sont évaluées pour déterminer si pour permettre la demande. Si une règle de correspondance accorde l'accès, la demande est autorisée. Si aucune règle de correspondance n'accorde l'accès, la demande est refusée.

// 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.
  }
}

Comme l'exemple ci - dessus montre, les path déclarations prend en charge les variables suivantes:

  • Joker-segment unique: Une variable générique est déclaré dans un trajet en enveloppant une variable entre accolades: {variable} . Cette variable est accessible dans le match de déclaration comme une string .
  • Génériques récursive: Le récursifs, ou multi-segments, les segments apparaissent génériques à trajets multiples au niveau ou en dessous d' un chemin d' accès. Ce caractère générique correspond à tous les chemins situés sous l'emplacement auquel vous l'avez défini. Vous pouvez le déclarer en ajoutant la =** chaîne à la fin de votre variable segment: {variable=**} . Cette variable est accessible dans le match de déclaration comme path objet.

Permettre

Le match de bloc contient un ou plusieurs allow des déclarations. Ce sont vos règles réelles. Vous pouvez appliquer allow des règles à une ou plusieurs méthodes. Les conditions sur une allow déclaration doit évaluer true pour Cloud Firestore ou Cloud Storage d'accorder toute demande entrante. Vous pouvez également écrire allow des déclarations sans conditions, par exemple, allow read de allow read . Si le allow cependant, il permet toujours la déclaration ne comprend pas une condition, la demande de cette méthode.

Si l' un des allow les règles de la méthode sont remplies, la demande est autorisée. De plus, si une règle plus large accorde l'accès, les règles accordent l'accès et ignorent les règles plus granulaires qui pourraient limiter l'accès.

Considérez l'exemple suivant, où n'importe quel utilisateur peut lire ou supprimer n'importe lequel de ses propres fichiers. Une règle plus précise n'autorise les écritures que si l'utilisateur qui demande l'écriture possède le fichier et que le fichier est au format PNG. Un utilisateur peut supprimer tous les fichiers du sous-chemin, même s'il ne s'agit pas de fichiers PNG, car la règle précédente le permet.

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

Méthode

Chaque allow déclaration comprend une méthode qui donne accès pour les requêtes entrantes de la même méthode.

Méthode Type de demande
Méthodes pratiques
read Tout type de demande de lecture
write Tout type de demande d'écriture
Méthodes standard
get Lire les demandes de documents ou de fichiers uniques
list Lire les demandes de requêtes et de collectes
create Écrire de nouveaux documents ou fichiers
update Écrire dans des documents de base de données existants ou mettre à jour les métadonnées du fichier
delete Suprimmer les données

Vous ne pouvez pas lire le chevauchement des méthodes dans la même match bloc ou méthodes d'écriture contradictoires dans la même path déclaration.

Par exemple, les règles suivantes échoueraient :

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

Fonction

Au fur et à mesure que vos règles de sécurité deviennent plus complexes, vous souhaiterez peut-être encapsuler des ensembles de conditions dans des fonctions que vous pourrez réutiliser dans votre ensemble de règles. Les règles de sécurité prennent en charge les fonctions personnalisées. La syntaxe des fonctions personnalisées ressemble un peu à JavaScript, mais les fonctions de règles de sécurité sont écrites dans un langage spécifique à un domaine qui présente des limitations importantes :

  • Les fonctions peuvent contenir qu'un seul return déclaration. Ils ne peuvent pas contenir de logique supplémentaire. Par exemple, ils ne peuvent pas exécuter de boucles ou appeler des services externes.
  • Les fonctions peuvent accéder automatiquement aux fonctions et variables à partir de la portée dans laquelle elles sont définies. Par exemple, une fonction définie dans le service cloud.firestore portée a accès à la resource variable et des fonctions intégrées telles que get() et exists() .
  • Les fonctions peuvent appeler d'autres fonctions mais ne peuvent pas se reproduire. La profondeur totale de la pile d'appels est limitée à 20.
  • Dans la version des règles v2 , les fonctions peuvent définir des variables à l' aide du let mot - clé. Les fonctions peuvent avoir jusqu'à 10 liaisons let, mais doivent se terminer par une instruction return.

Une fonction est définie par la function mot - clé et prend zéro ou plusieurs arguments. Par exemple, vous pouvez combiner les deux types de conditions utilisées dans les exemples ci-dessus en une seule fonction :

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

Voici un exemple montrant les arguments de fonction et les affectations let. Les instructions d'affectation Let doivent être séparées par des points-virgules.

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

Notez comment la isAdmin affectation applique une recherche de la collection admins. Pour l' évaluation paresseuse sans nécessiter des recherches inutiles, profiter de la nature à court-circuiter && (ET) et || (OR) pour appeler des comparaisons d' une deuxième fonction que si isAuthor se révèle être vrai (pour && comparaisons) ou faux (pour || comparaisons).

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

L'utilisation de fonctions dans vos règles de sécurité les rend plus faciles à gérer à mesure que la complexité de vos règles augmente.

Base de données en temps réel

Comme indiqué ci-dessus, les règles de base de données en temps réel comprennent trois éléments de base : l'emplacement de la base de données en tant que miroir de la structure JSON de la base de données, le type de demande et la condition d'octroi de l'accès.

Emplacement de la base de données

La structure de vos règles doit suivre la structure des données que vous avez stockées dans votre base de données. Par exemple, dans une application de chat avec une liste de messages, vous pourriez avoir des données qui ressemblent à ceci :

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

Vos règles doivent refléter cette structure. Par exemple:

  {
    "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()"
        }
      }
    }
  }

Comme l'exemple ci - dessus montre, en temps réel les règles de base de données prennent en charge un $location variable pour correspondre à des segments de chemin. Utilisez le $ préfixe devant votre segment de chemin pour correspondre à votre règle à tous les nœuds enfants le long du chemin.

  {
    "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')"
          }
        }
      }
    }
  }

Vous pouvez également utiliser la $variable en parallèle avec des noms de chemin constant.

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

Méthode

Dans Realtime Database, il existe trois types de règles. Deux de ces types de règles - read et write - appliquer la méthode d'une requête entrante. Le validate type de règle impose des structures de données et valide le format et le contenu des données. Les règles fonctionnent .validate règles après avoir vérifié qu'une .write règle autorise l' accès.

Types de règles
.lire Décrit si et quand les données sont autorisées à être lues par les utilisateurs.
.écrivez Décrit si et quand les données sont autorisées à être écrites.
.valider Définit à quoi ressemblera une valeur correctement formatée, si elle a des attributs enfants et le type de données.

Par défaut, s'il n'y a pas de règle l'autorisant, l'accès à un chemin est refusé.

Conditions de construction

Cloud Firestore

Une condition est une expression booléenne qui détermine si une opération particulière doit être autorisée ou refusée. La request et les resource variables fournissent le contexte de ces conditions.

La request de variable

La request variable comprend les champs suivants et les informations correspondantes:

request.auth

Un jeton Web JSON (JWT) qui contient les informations d'authentification de Firebase Authentication. auth jeton contient une série de revendications standard et toute réclamation personnalisés que vous créez par Firebase authentification. En savoir plus sur Firebase Règles et authentification de sécurité .

request.method

Le request.method peut être l' une des méthodes standard ou une méthode personnalisée. Les méthodes de commodité read et write existent aussi pour simplifier l' écriture de règles applicables à tous en lecture seule ou écriture toute seule des méthodes normalisées respectivement.

request.params

Les request.params comprennent toutes les données non liées spécifiquement à la request.resource qui pourraient être utiles pour l' évaluation. En pratique, cette carte doit être vide pour toutes les méthodes standard et doit contenir des données non-ressources pour les méthodes personnalisées. Les services doivent veiller à ne pas renommer ou modifier le type des clés et des valeurs présentées comme paramètres.

request.path

Le request.path est le chemin de la cible resource . Le chemin est relatif au service. Segments de chemin contenant des caractères non sûrs url tels que / sont encodées.

La resource la variable

La resource est la valeur actuelle à la fonction représentée par une carte de paires de valeurs de clé. Référençant resource dans un état entraînera au plus une lecture de la valeur du service. Cette recherche sera décomptée de tout quota lié au service pour la ressource. Pour get les demandes, la resource ne compte pour le quota nier.

Opérateurs et priorité des opérateurs

Utilisez le tableau ci-dessous comme référence pour les opérateurs et leur priorité correspondante dans les règles pour Cloud Firestore et Cloud Storage.

Compte tenu des expressions arbitraires a et b , un champ f , et un indice i .

Opérateur La description L'associativité
a[i] a() af Index, appel, accès au champ de gauche à droite
!a -a Négation unaire de droite à gauche
a/ba%ba*b Opérateurs multiplicatifs de gauche à droite
a+b ab Opérateurs additifs de gauche à droite
a>ba>=ba Opérateurs relationnels de gauche à droite
a in b Existence en liste ou carte de gauche à droite
a is type Comparaison de type, où le type peut être bool, int, float, numéro, chaîne, liste, carte, horodatage, la durée, le chemin ou latlng de gauche à droite
a==ba!=b Opérateurs de comparaison de gauche à droite
a && b ET conditionnel de gauche à droite
a || b OU conditionnel de gauche à droite
a ? true_value : false_value Expression ternaire de gauche à droite

Stockage en ligne

Une condition est une expression booléenne qui détermine si une opération particulière doit être autorisée ou refusée. La request et les resource variables fournissent le contexte de ces conditions.

La request de variable

La request variable comprend les champs suivants et les informations correspondantes:

request.auth

Un jeton Web JSON (JWT) qui contient les informations d'authentification de Firebase Authentication. auth jeton contient une série de revendications standard et toute réclamation personnalisés que vous créez par Firebase authentification. En savoir plus sur Firebase Règles et authentification de sécurité .

request.method

Le request.method peut être l' une des méthodes standard ou une méthode personnalisée. Les méthodes de commodité read et write existent aussi pour simplifier l' écriture de règles applicables à tous en lecture seule ou écriture toute seule des méthodes normalisées respectivement.

request.params

Les request.params comprennent toutes les données non liées spécifiquement à la request.resource qui pourraient être utiles pour l' évaluation. En pratique, cette carte doit être vide pour toutes les méthodes standard et doit contenir des données non-ressources pour les méthodes personnalisées. Les services doivent veiller à ne pas renommer ou modifier le type des clés et des valeurs présentées comme paramètres.

request.path

Le request.path est le chemin de la cible resource . Le chemin est relatif au service. Segments de chemin contenant des caractères non sûrs url tels que / sont encodées.

La resource la variable

La resource est la valeur actuelle à la fonction représentée par une carte de paires de valeurs de clé. Référençant resource dans un état entraînera au plus une lecture de la valeur du service. Cette recherche sera décomptée de tout quota lié au service pour la ressource. Pour get les demandes, la resource ne compte pour le quota nier.

Opérateurs et priorité des opérateurs

Utilisez le tableau ci-dessous comme référence pour les opérateurs et leur priorité correspondante dans les règles pour Cloud Firestore et Cloud Storage.

Compte tenu des expressions arbitraires a et b , un champ f , et un indice i .

Opérateur La description L'associativité
a[i] a() af Index, appel, accès au champ de gauche à droite
!a -a Négation unaire de droite à gauche
a/ba%ba*b Opérateurs multiplicatifs de gauche à droite
a+b ab Opérateurs additifs de gauche à droite
a>ba>=ba Opérateurs relationnels de gauche à droite
a in b Existence en liste ou carte de gauche à droite
a is type Comparaison de type, où le type peut être bool, int, float, numéro, chaîne, liste, carte, horodatage, la durée, le chemin ou latlng de gauche à droite
a==ba!=b Opérateurs de comparaison de gauche à droite
a && b ET conditionnel de gauche à droite
a || b OU conditionnel de gauche à droite
a ? true_value : false_value Expression ternaire de gauche à droite

Base de données en temps réel

Une condition est une expression booléenne qui détermine si une opération particulière doit être autorisée ou refusée. Vous pouvez définir ces conditions dans les règles de base de données en temps réel des manières suivantes.

Variables prédéfinies

Il existe un certain nombre de variables prédéfinies utiles auxquelles on peut accéder dans une définition de règle. Voici un bref résumé de chacun :

Variables prédéfinies
maintenant L'heure actuelle en millisecondes depuis l'époque Linux. Cela fonctionne particulièrement bien pour valider les horodatages créés avec firebase.database.ServerValue.TIMESTAMP du SDK.
racine Un RuleDataSnapshot représentant le chemin racine dans la base de données Firebase tel qu'il existe avant l'opération tentée.
nouvelles données Un RuleDataSnapshot représentant les données qu'il existerait après l'opération tentée. Il comprend les nouvelles données en cours d'écriture et les données existantes.
Les données Un RuleDataSnapshot représentant les données tel qu'il existait avant l'opération tentée.
$ variables Un chemin générique utilisé pour représenter les identifiants et les clés enfants dynamiques.
authentification Représente la charge utile du jeton d'un utilisateur authentifié.

Ces variables peuvent être utilisées n'importe où dans vos règles. Par exemple, les règles de sécurité ci - dessous en sorte que les données écrites sur le /foo/ nœud doit être une chaîne moins de 100 caractères:

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

Règles basées sur les données

Toutes les données de votre base de données peuvent être utilisées dans vos règles. En utilisant les variables prédéfinies root , les data et newData , vous pouvez accéder à tout chemin qu'il existerait avant ou après un événement d'écriture.

Considérons cet exemple, ce qui permet des opérations d'écriture aussi longtemps que la valeur du /allow_writes/ nœud est true , le nœud parent ne dispose pas d' un readOnly jeu de drapeau, et il y a un enfant nommé foo dans les nouvelles données écrites:

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

Règles basées sur des requêtes

Bien que vous ne puissiez pas utiliser de règles comme filtres, vous pouvez limiter l'accès à des sous-ensembles de données en utilisant des paramètres de requête dans vos règles. Utilisez la query. expressions dans vos règles pour accorder un accès en lecture ou en écriture en fonction des paramètres de requête.

Par exemple, la règle à base de requête suivante utilise des règles de sécurité basées sur l'utilisateur et les règles basées sur des requêtes pour restreindre l' accès aux données dans les baskets collection aux seuls paniers est propriétaire l'utilisateur actif:

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

La requête suivante, qui inclut les paramètres de requête dans la règle, aboutirait :

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

Cependant, les requêtes qui ne comprennent pas les paramètres de la règle échoueraient avec une PermissionDenied erreur:

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

Vous pouvez également utiliser des règles basées sur des requêtes pour limiter la quantité de données qu'un client télécharge via des opérations de lecture.

Par exemple, la règle suivante limite l'accès en lecture aux 1 000 premiers résultats d'une requête, par ordre de priorité :

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)

Ce qui suit query. Les expressions sont disponibles dans les règles de base de données en temps réel.

Expressions de règles basées sur des requêtes
Expression Taper La description
requête.orderByKey
query.orderByPriority
query.orderByValue
booléen True pour les requêtes classées par clé, priorité ou valeur. Faux sinon.
requête.orderByChild chaîne de caractères
nul
Utilisez une chaîne pour représenter le chemin relatif vers un nœud enfant. Par exemple, query.orderByChild == "address/zip" . Si la requête n'est pas triée par un nœud enfant, cette valeur est nulle.
requête.startAt
requête.endAt
query.equalTo
chaîne de caractères
numéro
booléen
nul
Récupère les limites de la requête en cours d'exécution ou renvoie null s'il n'y a pas de jeu de limites.
query.limitToFirst
requête.limitToLast
numéro
nul
Récupère la limite de la requête en cours d'exécution ou renvoie null si aucune limite n'est définie.

Les opérateurs

Règles en temps réel des bases de données prennent en charge un certain nombre d' opérateurs que vous pouvez utiliser pour combiner des variables dans l'instruction de condition. Voir la liste complète des opérateurs dans la documentation de référence .

Créer des conditions

Vos conditions réelles varieront en fonction de l'accès que vous souhaitez accorder. Les règles offrent intentionnellement un degré énorme de flexibilité, de sorte que les règles de votre application peuvent finalement être aussi simples ou aussi complexes que vous le souhaitez.

Pour quelques conseils simples création, règles prêtes pour la production, voir Règles de base de sécurité .