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

Structuration des règles de sécurité Cloud Firestore

Les règles de sécurité Cloud Firestore vous permettent de contrôler l'accès aux documents et aux collections de votre base de données. La syntaxe des règles flexible vous permet de créer des règles qui correspondent à tout, de toutes les écritures à l'ensemble de la base de données aux opérations sur un document spécifique.

Ce guide décrit la syntaxe de base et la structure des règles de sécurité. Combiner cette syntaxe avec des conditions de règles de sécurité pour créer des ensembles de règles complètes.

Déclaration de service et de base de données

Les règles de sécurité Cloud Firestore commencent toujours par la déclaration suivante :

service cloud.firestore {
  match /databases/{database}/documents {
    // ...
  }
}

Le service cloud.firestore déclaration oscilloscopes les règles de nuage Firestore, la prévention des conflits entre Cloud FireStore règles de sécurité et les règles pour d' autres produits tels que le Cloud Storage.

Les match /databases/{database}/documents de match /databases/{database}/documents de match /databases/{database}/documents de déclaration précise que les règles doivent correspondre à une base de données cloud Firestore dans le projet. Actuellement , chaque projet ne dispose que d' une seule base de données nommée (default) .

Règles de base en lecture/écriture

Les règles de base consistent en une match déclaration spécifiant un chemin de document et un allow l' expression des détails lors de la lecture des données spécifiées est autorisée:

service cloud.firestore {
  match /databases/{database}/documents {

    // Match any document in the 'cities' collection
    match /cities/{city} {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

Toutes les instructions de correspondance doivent pointer vers des documents, pas vers des collections. Une déclaration de correspondance peut pointer vers un document spécifique, comme dans match /cities/SF ou utiliser des jokers pour pointer vers un document dans le chemin d' accès spécifié, comme dans match /cities/{city} .

Dans l'exemple ci - dessus, la déclaration de correspondance utilise la {city} syntaxe générique. Cela signifie que la règle s'applique à tout document dans la cities collection, telles que /cities/SF ou /cities/NYC . Lorsque le allow les expressions dans la déclaration de correspondance sont évalués, la city Résout à la ville le nom du document, comme SF ou NYC .

Opérations granulaires

Dans certaines situations, il est utile de décomposer read et write dans des opérations plus granulaires. Par exemple, votre application peut vouloir appliquer des conditions différentes sur la création de document que sur la suppression de document. Ou vous pouvez autoriser la lecture d'un seul document mais refuser les requêtes volumineuses.

Une read règle peut être divisée en get et la list , tandis qu'une write règle peut être divisée en create , update à delete update et delete :

service cloud.firestore {
  match /databases/{database}/documents {
    // A read rule can be divided into get and list rules
    match /cities/{city} {
      // Applies to single document read requests
      allow get: if <condition>;

      // Applies to queries and collection read requests
      allow list: if <condition>;
    }

    // A write rule can be divided into create, update, and delete rules
    match /cities/{city} {
      // Applies to writes to nonexistent documents
      allow create: if <condition>;

      // Applies to writes to existing documents
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
}

Données hiérarchiques

Les données dans Cloud Firestore sont organisées en collections de documents, et chaque document peut étendre la hiérarchie via des sous-collections. Il est important de comprendre comment les règles de sécurité interagissent avec les données hiérarchiques.

Considérez la situation où chaque document dans la cities collection contient un landmarks subcollection. Les règles de sécurité ne concernent que sur le chemin adapté, de sorte que les contrôles d'accès définis dans les cities collection ne sont pas applicables aux landmarks de landmarks subcollection. À la place, écrivez des règles explicites pour contrôler l'accès aux sous-collections :

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      allow read, write: if <condition>;

        // Explicitly define rules for the 'landmarks' subcollection
        match /landmarks/{landmark} {
          allow read, write: if <condition>;
        }
    }
  }
}

Lors de l' imbrication match déclarations, le chemin du intérieur match de déclaration est toujours par rapport à la trajectoire de l'extérieur match de déclaration. Les ensembles de règles suivants sont donc équivalents :

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}
service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city}/landmarks/{landmark} {
      allow read, write: if <condition>;
    }
  }
}

Caractères génériques récursifs

Si vous voulez des règles à appliquer à une hiérarchie arbitraire profonde, utilisez la syntaxe générique récursif, {name=**} . Par exemple:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

Lors de l'utilisation de la syntaxe générique récursive, la variable générique contiendra l'intégralité du segment de chemin correspondant, même si le document se trouve dans une sous-collection profondément imbriquée. Par exemple, les règles énumérées ci - dessus correspondent seraient un document situé dans /cities/SF/landmarks/coit_tower , et la valeur du document de variable serait SF/landmarks/coit_tower .

Notez, cependant, que le comportement des caractères génériques récursifs dépend de la version des règles.

Version 1

Les règles de sécurité utilisent la version 1 par défaut. Dans la version 1, les caractères génériques récursifs correspondent à un ou plusieurs éléments de chemin. Ils ne correspondent pas à un chemin vide, donc match /cities/{city}/{document=**} correspond à des documents dans les sous - collections , mais pas dans les cities collection, alors que match /cities/{document=**} correspond à la fois les documents du cities collection et sous - collections.

Les caractères génériques récursifs doivent figurer à la fin d'une instruction de correspondance.

Version 2

Dans la version 2 des règles de sécurité, les caractères génériques récursifs correspondent à zéro ou plusieurs éléments de chemin. match/cities/{city}/{document=**} correspond à des documents dans toutes les sous - collections ainsi que des documents dans les cities collection.

Vous devez opt-in pour la version 2 en ajoutant rules_version = '2'; en haut de vos règles de sécurité :

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

Vous pouvez avoir au plus un caractère générique récursif par déclaration de correspondance, mais dans la version 2, vous pouvez placer ce caractère générique n'importe où dans la déclaration de correspondance. Par exemple:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the songs collection group
    match /{path=**}/songs/{song} {
      allow read, write: if <condition>;
    }
  }
}

Si vous utilisez des requêtes de groupe de collecte , vous devez utiliser la version 2, voir la sécurisation des requêtes de groupe de collecte .

Chevauchement des déclarations de correspondance

Il est possible pour un document pour correspondre à plus d'un match de déclaration. Dans le cas où plusieurs allow expressions correspondent à une demande, l'accès est autorisé si l' une des conditions est true :

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the 'cities' collection.
    match /cities/{city} {
      allow read, write: if false;
    }

    // Matches any document in the 'cities' collection or subcollections.
    match /cities/{document=**} {
      allow read, write: if true;
    }
  }
}

Dans l'exemple ci - dessus, toutes les lectures et les écritures cities collection seront autorisés parce que la deuxième règle est toujours true , même si la première règle est toujours false .

Limites des règles de sécurité

Lorsque vous travaillez avec des règles de sécurité, notez les limites suivantes :

Limite Des détails
Le nombre maximum de exists() , get() et getAfter() appelle par demande
  • 10 pour les demandes de document unique et les demandes de requête.
  • 20 pour les lectures multi-documents, les transactions et les écritures par lots. La limite précédente de 10 s'applique également à chaque opération.

    Par exemple, imaginez que vous créez une demande d'écriture groupée avec 3 opérations d'écriture et que vos règles de sécurité utilisent 2 appels d'accès au document pour valider chaque écriture. Dans ce cas, chaque écriture utilise 2 de ses 10 appels d'accès et la demande d'écriture par lots utilise 6 de ses 20 appels d'accès.

Le dépassement de l'une ou l'autre limite entraîne une erreur d'autorisation refusée.

Certains appels d'accès aux documents peuvent être mis en cache et les appels mis en cache ne sont pas pris en compte dans les limites.

Maximum imbriqué match de la profondeur de l' instruction dix
Longueur maximale du chemin, dans des segments de chemin, a permis dans un ensemble de imbriquées match déclarations 100
Le nombre maximum de chemins variables de capture autorisée dans un ensemble de imbriquées match déclarations 20
Profondeur maximale d'appel de fonction 20
Nombre maximum d'arguments de fonction 7
Nombre maximum de let liaisons variables par fonction dix
Nombre maximum d'appels de fonction récursifs ou cycliques 0 (non autorisé)
Nombre maximum d'expressions évaluées par requête 1 000
Taille maximale d'un ensemble de règles Les ensembles de règles doivent obéir à deux limites de taille :
  • une limite de 256 Ko de la taille de la source de texte publié à partir de la ruleset console Firebase ou de la CLI à l' aide firebase deploy .
  • une limite de 250 Ko sur la taille de l'ensemble de règles compilé qui se produit lorsque Firebase traite la source et la rend active sur le back-end.

Prochaines étapes