Правила Firestore для ролей и пользователей - PullRequest
0 голосов
/ 14 мая 2018

Я пытаюсь создать аналогичный, например, доступ на основе ролей (https://firebase.google.com/docs/firestore/solutions/role-based-access), в моей базе данных firestore. Но роли, как я их определил, не работают. Я всегда получаю ошибку с

Missing or insufficient permissions.

Что у меня есть, так это в правилах моего пожарного магазина:

service cloud.firestore {
  match /databases/{database}/documents {
  
    function isSignedIn() {
      return request.auth != null;
    }

    function getRole(rsc) {
      return rsc.data.roles[request.auth.uid];
    }

    function isOneOfRoles(rsc, array) {
      return isSignedIn() && (getRole(rsc) in array) || isSignedIn() && rsc.data.openWorld == true;
    }
  	
    match /users/{user} {
      allow read: if isSignedIn() && request.auth.uid == resource.data.uid;
    }
 
    // Match any document in the 'worlds' collection
    match /worlds/{world} {
      allow read: if isOneOfRoles(resource, ['owner', 'writer', 'commenter', 'reader']);
    }
  }
}

Моя структура документа выглядит следующим образом: ROOT / worlds / {WORLDID} / ... и каждый находящийся там документ выглядит следующим образом:

{
  name: "Open World",
  desc: "", 
  openWorld: true,
  roles: {
    DzpqsN6QjmZoCoM0eymWJ17VKbG3: "owner"
  }
}

Я использую это с Angular Frontedn и Angularfire со следующим кодом, который включен в сервис:

getWorlds(userId): Observable<any> {
  return this.afs.collection('worlds').snapshotChanges().map(actions => {
      return actions.map(a => {
        const data = a.payload.doc.data();
        const id = a.payload.doc.id;
        return { id, ...data };
      });
    }).catch((e: any) => Observable.throw(this.errorHandler(e)));
}

Кто-нибудь может увидеть, где там может быть ошибка или есть общая ошибка с firestore на данный момент?Спасибо!

1 Ответ

0 голосов
/ 14 мая 2018

Редактировать после вашего комментария:

Ваш запрос не выполнен "потому что он не включает в себя те же ограничения, что и ваши правила безопасности". См https://firebase.google.com/docs/firestore/security/rules-query#secure_and_query_documents_based_on_authuid.

Другими словами, вы не можете полагаться только на правило безопасности для фильтрации документов, которые пользователь может прочитать, и вы должны соответствующим образом построить свой запрос. Однако это не будет возможно с вашей текущей структурой данных, поскольку Firestore не поддерживает логические ИЛИ-запросы (например, следующее не будет возможным владельцем ИЛИ автором, владельцем ИЛИ openWorld и т. Д.).


Я тщательно проверил ваши правила, и они, кажется, работают правильно для всех случаев, т. Е. С различными ролями, в случае openWorld = true и не объявлена ​​правильная роль, в случае openWorld = false и т. Д. Вы уверены, что ваш пользователь правильно вошел в систему? Вы подождали достаточно времени, чтобы правила "распространились"?

Вот код JavaScript, используемый для тестирования

var docRef = firestoredb.collection("worlds").doc("x9fwf0Wi528OBlGYIZz1");

firebase.auth().signInWithEmailAndPassword("xxxx@xxx.com", "xxxxx")
    .then(function(userCredential) {

   docRef.get().then(function(doc) {
      if (doc.exists) {
          console.log("Document data:", doc.data());

      } else {
          // doc.data() will be undefined in this case
          console.log("No such document!");
      }

   }).catch(function(error) {
      console.log("Error getting document:", error);
   });

});

Наконец, вот предложение: я бы, возможно, реорганизовал бы ваши правила, чтобы отделить регистр isOneOfRoles и регистр isOpenWorld, например, например:

    function isOneOfRoles(rsc, array) {
      return isSignedIn() && (getRole(rsc) in array);
    }

    function isOpenWorld(rsc) {
      return isSignedIn() && rsc.data.openWorld == true;
    }

   .....

    // Match any document in the 'worlds' collection
    match /worlds/{world} {
      allow read: if isOneOfRoles(resource, ['owner', 'writer', 'commenter', 'reader']) || isOpenWorld(resource);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...