Firebase Security Rules pour Cloud Storage vous permet de contrôler l'accès aux objets stockés dans les 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, qu'il s'agisse de toutes les écritures dans votre bucket Cloud Storage ou des 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 ensembles 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 les 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 dans lesquelles l'accès est autorisé ou refusé.
Dans votre ensemble 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 aborderons plus en détail l'idée des correspondances génériques 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
.
Correspondance des 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 dont le nom comporte un préfixe de chaîne donné, 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 à partir de match
pour fournir l'autorisation du nom ou du chemin d'accès du fichier :
// 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 déjà dit, il n'y a pas de structure hiérarchique dans un bucket Cloud Storage. Toutefois, en utilisant une convention de dénomination de fichiers, qui inclut souvent 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.
Prenons l'exemple d'un ensemble de fichiers dont les noms commencent tous par la racine /images/
. Les Firebase Security Rules ne s'appliquent 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écursive
En plus des caractères génériques qui correspondent aux chaînes à la fin d'un nom de fichier et les renvoient, un caractère générique multisegment peut être déclaré pour une correspondance plus complexe 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 l'évaluation de toutes les 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
renvoient 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. Les règles ne sont évaluées que lorsque le chemin d'accès de la requête correspond à un chemin d'accès avec des règles spécifiées.
Version 1
Les Firebase Security Rules 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 nom de fichier, et non à zéro ou plusieurs éléments. Ainsi, 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 profiter de 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 seconde 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 sur les 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 modèle de nom de fichier et vous attendre à ce que Cloud Storage n'accède qu'aux fichiers auxquels le client actuel a accès.
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 dans 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
Pour mieux comprendre 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, et plus encore.
Examinez les cas d'utilisation de sécurité types et les définitions Firebase Security Rules qui y répondent.
Vous pouvez explorer les cas d'utilisation de Firebase Security Rules spécifiques à Cloud Storage :