Firebase Security Rules vous permettent de contrôler l'accès à vos données stockées. La syntaxe des règles flexibles vous permet de créer des règles qui correspondent à toutes sortes d'éléments : toutes les écritures de l'intégralité de la base de données, ou bien les opérations sur un document spécifique.
Ce guide décrit certains des cas d'utilisation les plus basiques que vous pouvez implémenter lorsque vous configurez votre application et protégez vos données. Toutefois, avant de commencer à écrire des règles, vous pouvez en savoir plus sur le langage dans lequel elles sont écrites et sur leur comportement.
Pour accéder à vos règles et les modifier, suivez les étapes décrites dans Gérer et déployer Firebase Security Rules.
Règles par défaut : mode verrouillé
Lorsque vous créez une base de données ou une instance de stockage dans la Firebase console, vous choisissez si vos Firebase Security Rules limitent l'accès à vos données (mode verrouillé) ou si elles autorisent l'accès à tous (mode test). Dans Cloud Firestore et Realtime Database, les règles par défaut du mode verrouillé refusent l'accès à tous les utilisateurs. Dans Cloud Storage, seuls les utilisateurs authentifiés peuvent accéder aux buckets de stockage.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
Realtime Database
{
"rules": {
".read": false,
".write": false
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if false;
}
}
}
Règles d'environnement de développement
Lorsque vous travaillez sur votre application, vous pouvez souhaiter un accès relativement ouvert ou illimité à vos données. Veillez simplement à modifier vos Security Rules avant de déployer votre application en production. N'oubliez pas non plus que si vous déployez votre application, elle est accessible au public, même si vous ne l'avez pas lancée.
N'oubliez pas que Firebase permet aux clients d'accéder directement à vos données et que Firebase Security Rules sont la seule protection qui bloque l'accès aux utilisateurs malveillants. Définir des règles séparément de la logique produit présente plusieurs avantages : les clients ne sont pas responsables de l'application de la sécurité, les implémentations boguées ne compromettent pas vos données et, surtout, vous ne comptez pas sur un serveur intermédiaire pour protéger les données du monde entier.
Tous les utilisateurs authentifiés
Bien que nous ne vous recommandions pas de laisser vos données accessibles à tous les utilisateurs qui sont connectés, il peut être utile de définir l'accès à tous les utilisateurs authentifiés lorsque vous développez votre application.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
match /some_collection/{document} {
allow read, write: if request.auth != null;
}
}
}
Realtime Database
{
"rules": {
"some_path": {
".read": "auth.uid !== null",
".write": "auth.uid !== null"
}
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
match /some_folder/{fileName} {
allow read, write: if request.auth != null;
}
}
}
Règles prêtes pour la production
Lorsque vous vous préparez à déployer votre application, assurez-vous que vos données sont protégées et que l'accès est correctement accordé à vos utilisateurs. Utilisez Authentication pour configurer l'accès basé sur l'utilisateur et lisez directement à partir de votre base de données pour configurer l'accès basé sur les données.
Envisagez d'écrire des règles lorsque vous structurez vos données, car la façon dont vous configurez vos règles a un impact sur la façon dont vous limitez l'accès aux données à différents chemins.
Accès limité au propriétaire du contenu
Ces règles limitent l'accès au seul propriétaire authentifié du contenu. Les données ne peuvent être lues et écrites que par un seul utilisateur, et le chemin d'accès aux données contient l'ID de l'utilisateur.
Quand cette règle fonctionne : cette règle fonctionne bien si les données sont isolées par utilisateur, c'est-à-dire si le seul utilisateur qui a besoin d'accéder aux données est le même que celui qui les a créées.
Quand cette règle ne fonctionne pas : cet ensemble de règles ne fonctionne pas lorsque plusieurs utilisateurs doivent écrire ou lire les mêmes données. Les utilisateurs écrasent les données ou ne peuvent pas accéder aux données qu'ils ont créées.
Pour configurer cette règle : créez une règle qui confirme que l'utilisateur qui demande l'accès en lecture ou en écriture aux données est celui qui en est propriétaire.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow only authenticated content owners access
match /some_collection/{userId}/{document} {
allow read, write: if request.auth != null && request.auth.uid == userId
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Allow only authenticated content owners access to their data
".read": "auth !== null && auth.uid === $uid",
".write": "auth !== null && auth.uid === $uid"
}
}
}
}
Cloud Storage
// Grants a user access to a node matching their user ID
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/file.txt"
match /user/{userId}/{fileName} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
Accès public et privé mixte
Cette règle permet à quiconque de lire un ensemble de données, mais limite la possibilité de créer ou de modifier des données à un chemin donné au seul propriétaire authentifié du contenu.
Quand cette règle fonctionne : cette règle fonctionne bien pour les applications qui nécessitent des éléments lisibles publiquement, mais qui doivent limiter l'accès en modification aux propriétaires de ces éléments. Par exemple, une application de chat ou un blog.
Quand cette règle ne fonctionne pas : comme la règle limitée au propriétaire du contenu, cet ensemble de règles ne fonctionne pas lorsque plusieurs utilisateurs doivent modifier les mêmes données. Les utilisateurs finiront par écraser les données des autres.
Pour configurer cette règle : créez une règle qui active l'accès en lecture pour tous les utilisateurs (ou tous les utilisateurs authentifiés) et qui confirme que l'utilisateur qui écrit des données est le propriétaire.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Allow public read access, but only content owners can write
match /some_collection/{document} {
// Allow public reads
allow read: if true
// Allow creation if the current user owns the new document
allow create: if request.auth.uid == request.resource.data.author_uid;
// Allow updates by the owner, and prevent change of ownership
allow update: if request.auth.uid == request.resource.data.author_uid
&& request.auth.uid == resource.data.author_uid;
// Allow deletion if the current user owns the existing document
allow delete: if request.auth.uid == resource.data.author_uid;
}
}
}
Realtime Database
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"some_path": {
"$uid": {
".read": true,
// or ".read": "auth.uid !== null" for only authenticated users
".write": "auth.uid === $uid"
}
}
}
}
Cloud Storage
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "user/<UID>/file.txt"
match /user/{userId}/{fileName} {
allow read;
allow write: if request.auth.uid == userId;
}
}
}
Accès basé sur des attributs et des rôles
Pour que cette règle fonctionne, vous devez définir et attribuer des attributs aux utilisateurs de vos données. Firebase Security Rules vérifient la requête par rapport aux données des métadonnées de votre base de données ou de votre fichier pour confirmer ou refuser l'accès.
Quand cette règle fonctionne : si vous attribuez un rôle aux utilisateurs, cette règle vous permet de limiter l'accès en fonction des rôles ou de groupes d'utilisateurs spécifiques. Par exemple, si vous stockez des notes, vous pouvez attribuer différents niveaux d'accès au groupe "élèves" (lecture de leur contenu uniquement), au groupe "enseignants" (lecture et écriture dans leur matière) et au groupe "directeurs" (lecture de tout le contenu).
Quand cette règle ne fonctionne pas : dans Realtime Database et Cloud Storage, vos règles
ne peuvent pas utiliser la méthode get() que les règles Cloud Firestore peuvent intégrer.
Par conséquent, vous devez structurer les métadonnées de votre base de données ou de votre fichier pour refléter
les attributs que vous utilisez dans vos règles.
Pour configurer cette règle : dans Cloud Firestore, incluez un champ dans les documents de vos utilisateurs que vous pouvez lire, puis structurez votre règle pour lire ce champ et accorder l'accès de manière conditionnelle. Dans Realtime Database, créez un chemin d'accès aux données qui définit les utilisateurs de votre application et leur attribue un rôle dans un nœud enfant.
Vous pouvez également configurer des revendications personnalisées dans Authentication
et ensuite récupérer ces informations à partir de la
auth.token variable dans n'importe quelle Firebase Security Rules.
Attributs et rôles définis par les données
Ces règles ne fonctionnent que dans Cloud Firestore et Realtime Database.
Cloud Firestore
N'oubliez pas que chaque fois que vos règles incluent une lecture, comme les règles ci-dessous, vous êtes facturé pour une opération de lecture dans Cloud Firestore.
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, Check a boolean `admin` attribute
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"${subpath}": {
//
".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
".read": true
}
}
}
}
Attributs et rôles de revendication personnalisés
Pour implémenter ces règles, configurez des revendications personnalisées dans Firebase Authentication et utilisez-les ensuite dans vos règles.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, check for an administrator claim
allow write: if request.auth.token.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if request.auth.token.reader == "true";
allow write: if request.auth.token.writer == "true";
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Create a custom claim for each role or group
// you want to use
".write": "auth.uid !== null && auth.token.writer === true",
".read": "auth.uid !== null && auth.token.reader === true"
}
}
}
}
Cloud Storage
service firebase.storage {
// 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;
}
}
Attributs de location
Pour implémenter ces règles, configurez la multitenancy dans Google Cloud Identity Platform (GCIP)
puis utilisez le locataire dans vos règles. Les exemples suivants autorisent les écritures
d'un utilisateur dans un locataire spécifique, par exemple tenant2-m6tyz.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For tenant-based access control, check for a tenantID
allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
allow read: true;
}
}
Realtime Database
{
"rules": {
"some_path": {
"$uid": {
// Only allow reads and writes if user belongs to a specific tenant
".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
".read": "auth.uid !== null
}
}
}
}
Cloud Storage
service firebase.storage {
// Only allow reads and writes if user belongs to a specific tenant
match /files/{tenantId}/{fileName} {
allow read: if request.auth != null;
allow write: if request.auth.token.firebase.tenant == tenantId;
}
}