Join us in person and online for Firebase Summit on October 18, 2022. Learn how Firebase can help you accelerate app development, release your app with confidence, and scale with ease. Register now

Conditions d'utilisation dans les règles de sécurité de Firebase Cloud Storage

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

Ce guide s'appuie sur l' apprentissage de la syntaxe de base du guide du langage des règles de sécurité Firebase pour montrer comment ajouter des conditions à vos règles de sécurité Firebase pour Cloud Storage.

Le bloc de construction principal des règles de sécurité Cloud Storage est la condition . Une condition est une expression booléenne qui détermine si une opération particulière doit être autorisée ou refusée. Pour les règles de base, l'utilisation de littéraux true et false comme conditions fonctionne parfaitement bien. Mais le langage Firebase Security Rules for Cloud Storage vous permet d'écrire des conditions plus complexes qui peuvent :

  • Vérifier l'authentification de l'utilisateur
  • Valider les données entrantes

Authentification

Les règles de sécurité Firebase pour Cloud Storage s'intègrent à Firebase Authentication pour fournir une authentification puissante basée sur l'utilisateur à Cloud Storage. Cela permet un contrôle d'accès granulaire basé sur les revendications d'un jeton d'authentification Firebase.

Lorsqu'un utilisateur authentifié effectue une requête auprès de Cloud Storage, la variable request.auth est renseignée avec l' uid de l'utilisateur ( request.auth.uid ) ainsi que les revendications du Firebase Authentication JWT ( request.auth.token ).

De plus, lors de l'utilisation d'une authentification personnalisée, des revendications supplémentaires apparaissent dans le champ request.auth.token .

Lorsqu'un utilisateur non authentifié effectue une requête, la variable request.auth est null .

À l'aide de ces données, il existe plusieurs façons courantes d'utiliser l'authentification pour sécuriser les fichiers :

  • Public : ignorer la request.auth
  • Privé authentifié : vérifiez que request.auth n'est pas null
  • Utilisateur privé : vérifiez que request.auth.uid est égal à un path uid
  • Groupe privé : vérifiez que les revendications du jeton personnalisé correspondent à une revendication choisie ou lisez les métadonnées du fichier pour voir si un champ de métadonnées existe

Public

Toute règle qui ne tient pas compte du contexte request.auth peut être considérée comme une règle public , car elle ne tient pas compte du contexte d'authentification de l'utilisateur. Ces règles peuvent être utiles pour afficher des données publiques telles que des éléments de jeu, des fichiers audio ou d'autres contenus statiques.

// Anyone to read a public image if the file is less than 100kB
// Anyone can upload a public file ending in '.txt'
match /public/{imageId} {
  allow read: if resource.size < 100 * 1024;
  allow write: if imageId.matches(".*\\.txt");
}

Privé authentifié

Dans certains cas, vous souhaiterez peut-être que les données soient visibles par tous les utilisateurs authentifiés de votre application, mais pas par les utilisateurs non authentifiés. La variable request.auth étant null pour tous les utilisateurs non authentifiés, il suffit de vérifier que la variable request.auth existe pour demander une authentification :

// Require authentication on all internal image reads
match /internal/{imageId} {
  allow read: if request.auth != null;
}

Utilisateur privé

Le cas d'utilisation de loin le plus courant pour request.auth sera de fournir aux utilisateurs individuels des autorisations granulaires sur leurs fichiers : du téléchargement de photos de profil à la lecture de documents privés.

Étant donné que les fichiers dans Cloud Storage ont un "chemin" complet vers le fichier, tout ce qu'il faut pour qu'un fichier soit contrôlé par un utilisateur est un élément d'information unique d'identification de l'utilisateur dans le préfixe du nom de fichier (comme l' uid de l'utilisateur) qui peut être vérifié lorsque la règle est évaluée :

// Only a user can upload their profile picture, but anyone can view it
match /users/{userId}/profilePicture.png {
  allow read;
  allow write: if request.auth.uid == userId;
}

Groupe privé

Un autre cas d'utilisation tout aussi courant consistera à autoriser des autorisations de groupe sur un objet, par exemple en permettant à plusieurs membres de l'équipe de collaborer sur un document partagé. Il existe plusieurs approches pour le faire :

  • Créer un jeton personnalisé d' authentification Firebase qui contient des informations supplémentaires sur un membre du groupe (comme un ID de groupe)
  • Inclure des informations de groupe (telles qu'un ID de groupe ou une liste d' uid autorisés) dans les métadonnées du fichier

Une fois ces données stockées dans les métadonnées du jeton ou du fichier, elles peuvent être référencées à partir d'une règle :

// Allow reads if the group ID in your token matches the file metadata's `owner` property
// Allow writes if the group ID is in the user's custom token
match /files/{groupId}/{fileName} {
  allow read: if resource.metadata.owner == request.auth.token.groupId;
  allow write: if request.auth.token.groupId == groupId;
}

Demande d'évaluation

Les importations, les téléchargements, les modifications de métadonnées et les suppressions sont évalués à l'aide de la request envoyée à Cloud Storage. En plus de l'ID unique de l'utilisateur et de la charge utile d'authentification Firebase dans l'objet request.auth comme décrit ci-dessus, la variable de request contient le chemin du fichier où la demande est effectuée, l'heure à laquelle la demande est reçue et la nouvelle valeur de resource si la requête est une écriture. Les en-têtes HTTP et l'état d'authentification sont également inclus.

L'objet de request contient également l'ID unique de l'utilisateur et la charge utile Firebase Authentication dans l'objet request.auth , qui sera expliqué plus en détail dans la section Sécurité basée sur l'utilisateur de la documentation.

Une liste complète des propriétés dans l'objet de request est disponible ci-dessous :

Propriété Taper La description
auth carte<chaîne, chaîne> Lorsqu'un utilisateur est connecté, fournit uid , l'ID unique de l'utilisateur et token , une carte des revendications Firebase Authentication JWT. Sinon, ce sera null .
params carte<chaîne, chaîne> Carte contenant les paramètres de requête de la requête.
path chemin Un path représentant le chemin sur lequel la requête est exécutée.
resource carte<chaîne, chaîne> La nouvelle valeur de ressource, présente uniquement sur les demandes d' write .
time horodatage Un horodatage représentant l'heure du serveur à laquelle la demande est évaluée.

Évaluation des ressources

Lors de l'évaluation des règles, vous pouvez également souhaiter évaluer les métadonnées du fichier en cours de chargement, de téléchargement, de modification ou de suppression. Cela vous permet de créer des règles complexes et puissantes qui autorisent uniquement le téléchargement de fichiers avec certains types de contenu ou la suppression de seuls fichiers supérieurs à une certaine taille.

Les règles de sécurité Firebase pour Cloud Storage fournissent des métadonnées de fichier dans l'objet de resource , qui contient des paires clé/valeur des métadonnées présentées dans un objet Cloud Storage. Ces propriétés peuvent être inspectées lors de demandes de read ou d' write pour garantir l'intégrité des données.

Sur les demandes d' write (telles que les téléchargements, les mises à jour de métadonnées et les suppressions), en plus de l'objet de resource , qui contient les métadonnées de fichier pour le fichier qui existe actuellement sur le chemin de la demande, vous avez également la possibilité d'utiliser l'objet request.resource , qui contient un sous-ensemble des métadonnées du fichier à écrire si l'écriture est autorisée. Vous pouvez utiliser ces deux valeurs pour garantir l'intégrité des données ou appliquer des contraintes d'application telles que le type ou la taille des fichiers.

Une liste complète des propriétés de l'objet resource est disponible ci-dessous :

Propriété Taper La description
name chaîne de caractères Le nom complet de l'objet
bucket chaîne de caractères Le nom du compartiment dans lequel cet objet réside.
generation entier La génération d'objet Google Cloud Storage de cet objet.
metageneration entier La métagénération d'objet Google Cloud Storage de cet objet.
size entier Taille de l'objet en octets.
timeCreated horodatage Un horodatage représentant l'heure à laquelle un objet a été créé.
updated horodatage Un horodatage représentant l'heure à laquelle un objet a été mis à jour pour la dernière fois.
md5Hash chaîne de caractères Un hachage MD5 de l'objet.
crc32c chaîne de caractères Un hachage crc32c de l'objet.
etag chaîne de caractères Etag associé à cet objet.
contentDisposition chaîne de caractères Disposition du contenu associée à cet objet.
contentEncoding chaîne de caractères Le codage de contenu associé à cet objet.
contentLanguage chaîne de caractères La langue du contenu associée à cet objet.
contentType chaîne de caractères Type de contenu associé à cet objet.
metadata carte<chaîne, chaîne> Paires clé/valeur de métadonnées personnalisées supplémentaires spécifiées par le développeur.

request.resource contient tous ces éléments à l'exception de generation , metageneration , etag , timeCreated et updated .

Valider les données

Les règles de sécurité Firebase pour Cloud Storage peuvent également être utilisées pour la validation des données, y compris la validation du nom et du chemin du fichier ainsi que les propriétés des métadonnées du fichier telles que contentType et size .

service firebase.storage {
  match /b/{bucket}/o {
    match /images/{imageId} {
      // Only allow uploads of any image file that's less than 5MB
      allow write: if request.resource.size < 5 * 1024 * 1024
                   && request.resource.contentType.matches('image/.*');
    }
  }
}

Fonctions personnalisées

Au fur et à mesure que vos règles de sécurité Firebase 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 des règles de sécurité Firebase sont écrites dans un langage spécifique à un domaine qui présente des limitations importantes :

  • Les fonctions ne peuvent contenir qu'une seule instruction de return . Ils ne peuvent contenir aucune 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 aux variables à partir de la portée dans laquelle elles sont définies. Par exemple, une fonction définie dans la portée du service firebase.storage a accès à la variable de resource et, pour Cloud Firestore uniquement, aux fonctions intégrées telles que get() et exists() .
  • Les fonctions peuvent appeler d'autres fonctions mais ne peuvent pas être récursives. La profondeur totale de la pile d'appels est limitée à 10.
  • Dans la version rules2 , les fonctions peuvent définir des variables à l'aide du mot clé let . Les fonctions peuvent avoir n'importe quel nombre de liaisons let, mais doivent se terminer par une instruction return.

Une fonction est définie avec le mot-clé function 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 firebase.storage {
  match /b/{bucket}/o {
    // 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 /images/{imageId} {
      allow read, write: if signedInOrPublic();
    }
    match /mp3s/{mp3Ids} {
      allow read: if signedInOrPublic();
    }
  }
}

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

Prochaines étapes

Après cette discussion sur les conditions, vous avez une compréhension plus sophistiquée des règles et êtes prêt à :

Apprenez à gérer les principaux cas d'utilisation et découvrez le flux de travail pour développer, tester et déployer des règles :