Aller au contenu principal

Flutter Règles d'accès Firebase

Règles de base à la création

À la création de votre DB Firestore, vous avez des règles d'accès qui ressemblent à ceci

Version de Test
rules_version = '2';

service cloud.firestore {

match /databases/{database}/documents {

match /{document=**} {
allow read, write: if request.time < timestamp.date(2024, 12, 14);
}
}

}

Structure des règles

Structure de base
rules_version = '2';

service cloud.firestore {
match /databases/{database}/documents {

//TODO l'instruction match sert à ajouter une règle d'accès
match /<some_path>/ {
//TODO on choisi ensuite le niveau de droit qu'on permet basé sur une condition
allow read, write: if <some_condition>;
}

}
}
Exemple d'utilisation
rules_version = '2';

service cloud.firestore {
match /databases/{database}/documents {

// Les règles s'appliquent pour toutes les villes de la collection
match /cities/{city} {
// Tout le monde peut lire les villes
allow read: if true;
// Disons que MX0zbHawfhWThfVO8J1oOFtgkfH2 est admin, seulement l'admin peut modifier les villes
allow write: if request.auth.uid == "MX0zbHawfhWThfVO8J1oOFtgkfH2"
}

// Les règles s'appliquent pour toutes les routes de la collection ou de toutes les sous-collections
// {document=**} est un wildchar qui permet d'appliquer la règle à tous les documents de façon récursive
match /cities/{city}/roads/{document=**} {
// Tout le monde peut lire et écrire
allow read, write: if true;
}
}
}

Tester nos règles

  • On peut également utiliser l'espace de test pour valider nos nouvelles règles

Capture de l&#39;espace de test des règles Firebase

  • On peut choisir le type d'opération à tester, le chemin vers le document qu'on voudrait accéder et l'authentification de l'utilisateur

Capture montrant le choix de l&#39;opération, du chemin et de l&#39;authentification pour tester des règles Firebase

  • Ici, on valide l'accès en lecture au document "Longueuil" dans la collection de villes pour tous les utilisateurs

Capture montrant une validation de lecture sur un document Firebase

  • On valide maintenant l'accès mais cette fois si en écriture
  • On remarque une erreur dans les règles, l'objet request.auth est null, donc request.auth.uid donne "Null value error"

Capture montrant un échec de validation en écriture à cause d&#39;une authentification absente

  • On corrige le tout pour relancer la validation

Capture montrant la correction des règles Firebase avant une nouvelle validation

  • On ajoute un utilisateur pour valider les droits "admin"

Capture montrant l&#39;ajout d&#39;un utilisateur pour tester des droits administrateur

  • Finalement, on test l'accès à toutes les sous-collections

Capture montrant le test d&#39;accès aux sous-collections Firebase

Valider qu'un utilisateur est connecté

Les informations de connexions de l'utilisateur se trouve dans l'objet request.auth

Permettre la lecture à tous mais l'écriture seulement aux utilisateurs connectés
rules_version = '2';

service cloud.firestore {
match /databases/{database}/documents {

match /{document=**} {
// Tout le monde peut lire
allow read: if true;
// On doit être connecté pour écrire (CREATE, UPDATE, DELETE)
allow write: if request.auth !=null
}

}
}

Plusieurs règles sur un même document

  • Il est possible que plusieurs règles s'appliquent sur un même document
  • Dès qu'une règle a la valeur true, l'accès est accordé

Capture montrant plusieurs règles applicables sur un même document Firebase

  • Ici, si l'on veut vraiment interdire la suppression, il faudra être plus précis

Capture montrant un cas où la suppression doit être explicitement interdite dans les règles Firebase

Ajouter une "variable" / paramètre

Match avec un document par le id

Utiliser un paramètre dans la route
rules_version = '2';

service cloud.firestore {
match /databases/{database}/documents {

// {userid} crée un paramètre pour notre règle
// Ça fonctionne un peu comme une route en ASP.Net
match /users/{userid} {
// Seulement l'utilisateur lui-même peut avoir accès à ses données
allow read, write: if request.auth !=null && request.auth.uid == userid
}

}
}

Match avec un document par valeur d'un champ

  • Pour valider avec un champ, on doit aller lire le document
  • On peut lire un champ avec la méthode get(path)
Récupérer un document
rules_version = '2';

service cloud.firestore {
match /databases/{database}/documents {

match /users/{user} {
// Seulement un utilisateur avec le rôle admin peut avoir accès aux utilisateurs
allow read, write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "admin";
}

}
}
  • Comme que ça peut faire de longues conditions, on peut faire des fonctions
Faire des fonctions
rules_version = '2';

service cloud.firestore {
match /databases/{database}/documents {

// On crée une fonction pour valider que l'utilisateur connecté est un admin
function isAdmin() {
return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "admin";
}

match /users/{userid} {
// On utilise notre fonction
allow read, write: if isAdmin();
}

}
}