Firebase Security Rules pour Cloud Storage vous permet de contrôler l'accès aux objets stockés dans des buckets Cloud Storage. La syntaxe des règles flexibles vous permet de créer des règles pour contrôler n'importe quelle opération, de toutes les écritures dans votre bucket Cloud Storage aux opérations sur un fichier spécifique.
Ce guide décrit la syntaxe et la structure de base de Cloud Storage Security Rules pour créer des jeux de règles complets.
Déclaration de service et de base de données
Les Firebase Security Rules pour Cloud Storage commencent toujours par la déclaration suivante:
service firebase.storage {
// ...
}
La déclaration service firebase.storage
définit les règles pour Cloud Storage, en évitant les conflits entre Cloud Storage Security Rules et les règles pour d'autres produits tels que Cloud Firestore.
Règles de base pour les lectures et les écritures
Les règles de base comprennent une instruction match
identifiant des buckets Cloud Storage, une instruction de correspondance spécifiant un nom de fichier et une expression allow
détaillant la lecture des données spécifiées. Les expressions allow
spécifient les méthodes d'accès (par exemple, lecture, écriture) impliquées et les conditions sous lesquelles l'accès est autorisé ou refusé.
Dans votre jeu de règles par défaut, la première instruction match
utilise une expression générique {bucket}
pour indiquer que les règles s'appliquent à tous les buckets de votre projet. Nous reviendrons sur les expressions régulières dans la section suivante.
service firebase.storage {
// The {bucket} wildcard indicates we match files in all Cloud Storage buckets
match /b/{bucket}/o {
// Match filename
match /filename {
allow read: if <condition>;
allow write: if <condition>;
}
}
}
Toutes les instructions de correspondance pointent vers des fichiers. Une instruction de correspondance peut pointer vers un fichier spécifique, comme dans match /images/profilePhoto.png
.
Correspondre aux caractères génériques
En plus de pointer vers un seul fichier, Rules peut utiliser des caractères génériques pour pointer vers n'importe quel fichier portant un préfixe de chaîne donné dans son nom, y compris des barres obliques, comme dans match /images/{imageId}
.
Dans l'exemple ci-dessus, l'instruction de correspondance utilise la syntaxe de caractère générique {imageId}
.
Cela signifie que la règle s'applique à tous les fichiers dont le nom commence par /images/
, tels que /images/profilePhoto.png
ou /images/croppedProfilePhoto.png
. Lorsque les expressions allow
dans l'instruction de correspondance sont évaluées, la résolution de la variable imageId
donne le nom de fichier de l'image, tel que profilePhoto.png
ou croppedProfilePhoto.png
.
Une variable générique peut être référencée dans match
pour fournir une autorisation de nom de fichier ou de chemin d'accès:
// Another way to restrict the name of a file
match /images/{imageId} {
allow read: if imageId == "profilePhoto.png";
}
Données hiérarchisées
Comme nous l'avons indiqué précédemment, il n'y a pas de structure hiérarchique dans un bucket Cloud Storage. Toutefois, en utilisant une convention d'attribution de noms de fichiers, souvent celle qui inclut des barres obliques dans les noms de fichiers, nous pouvons imiter une structure qui ressemble à une série imbriquée de répertoires et de sous-répertoires. Il est important de comprendre comment Firebase Security Rules interagit avec ces noms de fichiers.
Imaginons un ensemble de fichiers dont les noms commencent tous par la racine /images/
. Firebase Security Rules ne s'applique qu'au nom de fichier correspondant. Par conséquent, les contrôles d'accès définis sur la racine /images/
ne s'appliquent pas à la racine /mp3s/
.
À la place, écrivez des règles explicites qui correspondent à différents modèles de nom de fichier:
service firebase.storage {
match /b/{bucket}/o {
match /images/{imageId} {
allow read, write: if <condition>;
}
// Explicitly define rules for the 'mp3s' pattern
match /mp3s/{mp3Id} {
allow read, write: if <condition>;
}
}
}
Lors de l'imbrication des instructions match
, le chemin de l'instruction interne match
est toujours ajouté au chemin de l'instruction externe match
. Les deux ensembles de règles suivants sont donc équivalents:
service firebase.storage {
match /b/{bucket}/o {
match /images {
// Exact match for "images/profilePhoto.png"
match /profilePhoto.png {
allow write: if <condition>;
}
}
}
}
service firebase.storage {
match /b/{bucket}/o {
// Exact match for "images/profilePhoto.png"
match /images/profilePhoto.png {
allow write: if <condition>;
}
}
}
Caractères génériques de correspondance récursifs
En plus des caractères génériques qui correspondent et renvoient des chaînes à la fin d'un nom de fichier, un caractère générique multisegment peut être déclaré pour des correspondances plus complexes en ajoutant =**
au nom du caractère générique, comme {path=**}
:
// Partial match for files that start with "images"
match /images {
// Exact match for "images/**"
// e.g. images/users/user:12345/profilePhoto.png is matched
// images/profilePhoto.png is also matched!
match /{allImages=**} {
// This rule matches one or more path segments (**)
// allImages is a path that contains all segments matched
allow read: if <other_condition>;
}
}
Si plusieurs règles correspondent à un fichier, le résultat est le OR
du résultat de toutes les évaluations de règles. Autrement dit, si une règle à laquelle le fichier correspond est évaluée à true
, le résultat est true
.
Dans les règles ci-dessus, le fichier "images/profilePhoto.png" peut être lu si condition
ou other_condition
renvoie la valeur "true", tandis que le fichier "images/users/user:12345/profilePhoto.png" n'est soumis qu'au résultat de other_condition
.
Les Cloud Storage Security Rules ne sont pas en cascade, et les règles ne sont évaluées que lorsque le chemin de requête correspond à un chemin avec des règles spécifiées.
Version 1
Firebase Security Rules utilise 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 nom de fichier, et non à zéro ou plusieurs éléments. Par conséquent, match /images/{filenamePrefixWildcard}/{imageFilename=**}
correspond à un nom de fichier tel que /images/profilePics/profile.png, mais pas à /images/badge.png. Utilisez plutôt /images/{imagePrefixorFilename=**}
.
Les caractères génériques récursifs doivent apparaître à la fin d'une instruction de correspondance.
Nous vous recommandons d'utiliser la version 2 pour ses fonctionnalités plus puissantes.
Version 2
Dans la version 2 de Firebase Security Rules, les caractères génériques récursifs peuvent correspondre à zéro, un ou plusieurs éléments de chemin. Par conséquent, /images/{filenamePrefixWildcard}/{imageFilename=**}
correspond aux noms de fichiers /images/profilePics/profile.png et /images/badge.png.
Vous devez activer la version 2 en ajoutant rules_version = '2';
en haut de vos règles de sécurité :
rules_version = '2';
service cloud.storage {
match /b/{bucket}/o {
...
}
}
Vous pouvez utiliser au maximum un caractère générique récursif par requête, mais dans la version 2, vous pouvez placer ce caractère générique n'importe où dans l'instruction de correspondance. Exemple :
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// Matches any file in a songs "subdirectory" under the
// top level of your Cloud Storage bucket.
match /{prefixSegment=**}/songs/{mp3filenames} {
allow read, write: if <condition>;
}
}
}
Opérations précises
Dans certains cas, il est utile de décomposer les opérations read
et write
en opérations plus précises. Par exemple, votre application peut vouloir appliquer des conditions différentes à la création de fichiers et à la suppression de fichiers.
Une opération read
peut être divisée en get
et list
.
Une règle write
peut être divisée en create
, update
et delete
:
service firebase.storage { match /b/{bucket}/o { // A read rule can be divided into read and list rules match /images/{imageId} { // Applies to single file read requests allow get: if <condition>; // Applies to list and listAll requests (Rules Version 2) allow list: if <condition>; // A write rule can be divided into create, update, and delete rules match /images/{imageId} { // Applies to writes to file contents allow create: if <condition>; // Applies to updates to (pre-existing) file metadata allow update: if <condition>; // Applies to delete operations allow delete: if <condition>; } } } }
Chevauchement d'instructions de correspondance
Il est possible qu'un nom de fichier corresponde à plusieurs instructions match
. Dans le cas où plusieurs expressions allow
correspondent à une requête, l'accès est autorisé si au moins une des conditions est définie sur true
:
service firebase.storage {
match b/{bucket}/o {
// Matches file names directly inside of '/images/'.
match /images/{imageId} {
allow read, write: if false;
}
// Matches file names anywhere under `/images/`
match /images/{imageId=**} {
allow read, write: if true;
}
}
}
Dans l'exemple ci-dessus, toutes les lectures et écritures dans les fichiers dont le nom commence par /images/
sont autorisées, car la deuxième règle est toujours true
, même lorsque la première règle est false
.
Les règles ne sont pas des filtres
Une fois que vous avez sécurisé vos données et que vous commencez à effectuer des opérations de fichiers, gardez à l'esprit que les règles de sécurité ne sont pas des filtres. Vous ne pouvez pas effectuer d'opérations sur un ensemble de fichiers correspondant à un format de nom de fichier et vous attendre à ce que Cloud Storage n'accède qu'aux fichiers auxquels le client actuel est autorisé à accéder.
Prenons l'exemple de la règle de sécurité suivante :
service firebase.storage {
match /b/{bucket}/o {
// Allow the client to read files with contentType 'image/png'
match /aFileNamePrefix/{aFileName} {
allow read: if resource.contentType == 'image/png';
}
}
}
Refusé: cette règle rejette la requête suivante, car l'ensemble de résultats peut inclure des fichiers où le champ contentType
ne contient pas la valeur image/png
:
Web
filesRef = storage.ref().child("aFilenamePrefix"); filesRef.listAll() .then(function(result) { console.log("Success: ", result.items); }) });
Les règles de Cloud Storage Security Rules évaluent chaque requête par rapport à son résultat potentiel ; la requête échoue si elle peut renvoyer un fichier que le client n'est pas autorisé à lire. Les demandes d'accès doivent respecter les contraintes définies par vos règles.
Étapes suivantes
Vous pouvez approfondir votre compréhension de Firebase Security Rules pour Cloud Storage:
Découvrez le prochain concept majeur du langage Rules : les conditions dynamiques, qui permettent à vos règles de vérifier l'autorisation des utilisateurs, de comparer les données existantes et entrantes, de valider les données entrantes, etc.
Consultez les cas d'utilisation de sécurité courants et les définitions Firebase Security Rules qui les traitent.
Vous pouvez explorer les cas d'utilisation Firebase Security Rules spécifiques à Cloud Storage: