Firebase: ensemble des règles de sécurité en fonction des rôles de l'utilisateur

Je tiens à mettre en œuvre "écrire" des règles de sécurité Firebase selon les utilisateurs des rôles.

Ma structure de données est comme ceci:

+ myapp
  + users
    + john
      + email: "[email protected]"
      + roles
        + administrator: true
    + mary
      + email: "[email protected]"
      + roles
        + moderator: true
    + ...
  + documents
    + -JVmo6wZM35ZQr0K9tJu
      + ...
    + -JVr56hVTZxlAI5AgUaS
      + ...
    + ...

Je veux que, par exemple, que seul l'administrateur les utilisateurs peuvent écrire des documents.

Ce sont les règles, je viens à:

{
  "rules": {
    ".read": true,
    "$documents": {
      ".write": "root.child('users').child(auth.uid).child('roles').child('administrator').val() === true"
    }
  }
}

Mais ça ne fonctionne pas: pas même administrateur les utilisateurs peuvent écrire des documents...

Est ma compréhension de Firebase règles de sécurité totalement erronée?

Mise à JOUR:
Juste avant de Jenny réponse (croyez-le ou pas :-), je n'ai appliquer exactement la même solution qu'il fournit (des cours sur la base de Kato commentaire).

Cependant, faire quelques tests, je ne pouvais pas laisser la structure des règles

{
  "rules": {
    "documents" {
      "$document" {
        ".read": "root.child('users').child(auth.uid).child('roles').child('documents').child('read').val() === true",
        ".write": "root.child('users').child(auth.uid).child('roles').child('documents').child('write').val() === true"
      }
    }
  }
}

travail... j'ai toujours eu un avertissement comme ceci:

"FIREBASE WARNING: on() or once() for /documents failed: Error: permission_denied: Client doesn't have permission to access the desired data. "

Alors je suis venu avec cette structure, au lieu de:

{
  "rules": {
    "documents" {
      ".read": "root.child('users').child(auth.uid).child('roles').child('documents').child('read').val() === true",
      ".write": "root.child('users').child(auth.uid).child('roles').child('documents').child('write').val() === true"
    }
  }
}

Qui fonctionne vraiment, pour moi: si j'ai mis un des rôles/clients/lire nœud de vrai sur un utilisateur, il peut lire tous les documents, sinon il ne peut pas (et de même pour l'écriture).

Mes doutes sont maintenant:

  • pourquoi je ne pouvais pas laisser la première règle (comme suggéré par Kato) de travail?
  • voyez-vous une faille de sécurité possible dans une règle comme celui que j'ai fait est venu avec?
  • sont les règles à l'aide de "$", les variables nécessaires et/ou utiles, même si vous n'avez pas à autoriser/refuser la lisibilité/writeability de chaque
    document sur la base de sa clé, mais vous voulez juste pour permettre/interdire le
    lisibilité/writeability d'un nœud dans son ensemble?
  • Basé sur les noms de vos enregistrements d'utilisateur, je suppose qu'ils ne correspondent pas auth.uid (qui est probablement un simple id de connexion, tels que twitter:2544215). Aussi, votre .write règle devrait probablement être sous documents/$document au lieu de $documents (hors de la racine), sinon, vous serez en permettant d'accéder à n'importe quel chemin sur la racine.
  • Merci, Kato!... Je vais certainement changer la clé de mes utilisateurs (du nom d'utilisateur uid). Est-ce une pratique courante (indexation des utilisateurs par uid)? Que faire si je souhaite afin de permettre plusieurs fournisseurs d'authentification pour le même utilisateur (par exemple, 'twitter' et 'mot de passe')? Je devrais résultat avec le même utilisateur, sous de multiples clés... 🙁 Mais, tout d'abord, dois-je ajouter un utilisateur à mes Utilisateurs de collecte si elle se connecte avec un "social" fournisseur, ou devrais-je signer son dans?
  • Toutes ces questions sont de la propriété de votre cas d'utilisation. Vous voulez probablement pour stocker des données concernant les utilisateurs, indépendamment de la façon dont ils se connectent. Je ne connais pas de sites qui vous permettent de vous connecter à un compte à partir de plusieurs fournisseurs (c'est à dire des identités distinctes) autres que le total des services qui combinent du contenu de flux provenant des différents services. Si vous souhaitez prendre cette route, de générer vos propres jetons et id.
  • Non, je ne veux pas prendre cette route... j'ai juste pensé que c'était une pratique courante (et attendues par les utilisateurs "ordinaires"). Si je peux accepter un seul prestataire pour l'utilisateur, tout est plus simple, et je peux utiliser les uid de l'index de mes utilisateurs... Merci pour l'explication...
  • Vous pouvez effectuer plusieurs fournisseurs d'authentification par l'utilisateur par l'utilisation de plus d'un nœud pour les stocker. Il faudrait que certains potentiellement dangereux hypothèses de boulangerie en elle, cependant, puisque vous aurez besoin d'un identifiant commun pour se joindre à eux (comme le courrier électronique). Mais je m'égare. Si vous souhaitez explorer, poser une autre question et je vais répondre là 🙂
  • Merci, Jenny... Pour le moment je vais rester avec un fournisseur d'accès par utilisateur... Cependant, même si l'e-mail est un bon candidat pour rejoindre les nœuds, je suppose qu'il n'est pas possible, étant donné que tous les fournisseurs (voir twitter, par exemple) ne le retourner...
  • J'ai mis à jour ma réponse à couvrir les points 1 et 3. Comme pour les 2, votre rôle de sécurité me semble bon. Nous sommes en indiquant à m'égare un peu, cependant. Si vous avez plus de questions au sujet de $variables dans auth, pouvez-vous poser une nouvelle question? 🙂

InformationsquelleAutor MarcoS | 2014-09-03