Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Apprenez la syntaxe de base du langage Firebase Security Rules for Cloud Storage

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

Les règles de sécurité Firebase pour Cloud Storage vous permettent de contrôler l'accès aux objets stockés dans les buckets Cloud Storage. La syntaxe de règles flexible 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 des règles de sécurité Cloud Storage pour créer des ensembles de règles complets.

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

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

service firebase.storage {
    // ...
}

La déclaration service firebase.storage les règles à Cloud Storage, évitant ainsi les conflits entre les règles de sécurité Cloud Storage et les règles d'autres produits tels que Cloud Firestore.

Règles de lecture/écriture de base

Les règles de base consistent en une instruction de match identifiant les buckets Cloud Storage, une instruction de correspondance spécifiant un nom de fichier et une expression d' allow indiquant quand la lecture des données spécifiées est autorisée. 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 de match utilise une expression générique {bucket} pour indiquer que les règles s'appliquent à tous les buckets de votre projet. Nous discuterons davantage de 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 match peut pointer vers un fichier spécifique, comme dans match /images/profilePhoto.png .

Faire correspondre les caractères génériques

En plus de pointer vers un seul fichier, les règles peuvent utiliser des caractères génériques pour pointer vers n'importe quel fichier avec 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 match utilise la syntaxe générique {imageId} . Cela signifie que la règle s'applique à tout fichier avec /images/ au début de son nom, tel que /images/profilePhoto.png ou /images/croppedProfilePhoto.png . Lorsque les expressions allow dans l'instruction match sont évaluées, la variable imageId sera résolue en nom de fichier image, tel que profilePhoto.png ou croppedProfilePhoto.png .

Une variable générique peut être référencée à partir de la match pour fournir un nom de fichier ou une autorisation de chemin :

// Another way to restrict the name of a file
match /images/{imageId} {
  allow read: if imageId == "profilePhoto.png";
}

Données hiérarchiques

Comme nous l'avons déjà dit, il n'y a pas de structure hiérarchique à l'intérieur d'un bucket Cloud Storage. Mais en utilisant une convention de nommage de fichiers, souvent une convention 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 les règles de sécurité Firebase interagissent avec ces noms de fichiers.

Considérez la situation d'un ensemble de fichiers dont les noms commencent tous par la racine /images/ . Les règles de sécurité de Firebase s'appliquent uniquement au nom de fichier correspondant, de sorte que les contrôles d'accès définis sur la racine /images/ ne s'appliquent pas à la racine /mp3s/ . Au lieu de cela, écrivez des règles explicites qui correspondent à différents modèles de noms de fichiers :

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 d'instructions de match , le chemin de l'instruction de match interne est toujours ajouté au chemin de l'instruction de match externe. 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 à plusieurs segments 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 l' OR du résultat de toutes les évaluations de règles. Autrement dit, si une règle que 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 l'une ou l'autre condition ou other_condition évaluée à true, tandis que le fichier "images/users/user:12345/profilePhoto.png" n'est soumis qu'au résultat de other_condition .

Les règles de sécurité Cloud Storage ne se cascadent pas et les règles ne sont évaluées que lorsque le chemin de la demande correspond à un chemin avec les règles spécifiées.

Version 1

Les règles de sécurité Firebase 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 comme /images/profilePics/profile.png, mais pas /images/badge.png. Utilisez plutôt /images/{imagePrefixorFilename=**} .

Les caractères génériques récursifs doivent figurer à 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 des règles de sécurité Firebase, les caractères génériques récursifs correspondent à zéro ou plusieurs éléments de chemin. Ainsi, /images/{filenamePrefixWildcard}/{imageFilename=**} correspond aux noms de fichiers /images/profilePics/profile.png et /images/badge.png.

Vous devez vous inscrire à la version 2 en ajoutant rules_version = '2'; au sommet de vos règles de sécurité :

rules_version = '2';
service cloud.storage {
  match /b/{bucket}/o {
   ...
 }
}

Vous pouvez avoir au plus un caractère générique récursif par instruction de correspondance, mais dans la version 2, vous pouvez placer ce caractère générique n'importe où dans l'instruction de correspondance. Par 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 granulaires

Dans certaines situations, il est utile de décomposer la read et l' write en opérations plus granulaires. Par exemple, votre application peut souhaiter appliquer des conditions différentes à la création de fichiers et à la suppression de fichiers.

Une opération de read peut être décomposée en get et list .

Une règle d' write peut être décomposé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 des déclarations de correspondance

Il est possible qu'un nom de fichier corresponde à plusieurs instructions de match . Dans le cas où plusieurs expressions d' allow correspondent à une requête, l'accès est autorisé si l'une des conditions est 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 commencé à 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 accède uniquement aux fichiers auxquels le client actuel est autorisé à accéder.

Prenons par exemple 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 le jeu de résultats peut inclure des fichiers où contentType n'est pas image/png :

la toile
filesRef = storage.ref().child("aFilenamePrefix");

filesRef.listAll()
    .then(function(result) {
      console.log("Success: ", result.items);
    })
});

Les règles des règles de sécurité de Cloud Storage évaluent chaque requête par rapport à son résultat potentiel et font échouer la requête 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.

Prochaines étapes

Vous pouvez approfondir votre compréhension des règles de sécurité Firebase pour Cloud Storage :

  • Découvrez le prochain concept majeur du langage des règles, 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.

  • Passez en revue les cas d'utilisation de sécurité typiques et les définitions des règles de sécurité Firebase qui les traitent .

Vous pouvez explorer les cas d'utilisation des règles de sécurité Firebase spécifiques à Cloud Storage :