将自定义声明与Firestore文档ID匹配

时间:2018-10-08 05:34:33

标签: firebase google-cloud-firestore firebase-security firebase-security-rules

我的数据大致如下:

/databases/schools/{schoolId}/faculty
                             /students
                             /etc

我有一群人的帐户上有customClaim“ schoolId”。我只希望他们能够访问他们所属学校的教职员工。尝试了此规则的许多迭代,最新的是

service cloud.firestore {
  match /databases/schools/{document} {
    match /{doc=**} {
      allow read, write: if user.token.schoolId == document;
    }
  }
}

其他迭代包括:

service cloud.firestore {
  match /databases/schools/{document} {
    allow read, write: if user.token.schoolId == document;
  }
}

service cloud.firestore {
  match /databases/schools {
    match /{document=**} {
      allow read, write: if user.token.schoolId == document;
    }
  }
}

service cloud.firestore {
  match /databases/{database}/documents {
    match /{$document} {
      allow read, write: if resource.id == user.token.schoolId;
    }
  }
}

这感觉应该很简单,但是我无法弄清楚(我正在第12次迭代)

我认为我理解最后一个不起作用,因为如果我尝试获取/ databases / schools / school1 / faculty / abc123,那么resource.id实际上是指abc123而不是school1。

当我解码令牌时,一个示例用户如下所示:

uid: "gobblygook"
displayName: null
photoURL: null
email: "test-email@yopmail.com"
emailVerified: true
phoneNumber: null
isAnonymous: false
apiKey: "{apikey}"
appName: "[DEFAULT]"
authDomain: "{mydomain}.firebaseapp.com"
lastLoginAt: "1538972960000"
createdAt: "1538868952000"
schoolId: "school1"

2 个答案:

答案 0 :(得分:0)

以下方法应该起作用:

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

     match schools/{schoolId} {
       allow read: if request.auth.token.schoolId == resource.data.schoolId;
       allow write: if request.auth.token.schoolId == request.resource.data.schoolId;
     }        

  }
}

请注意:

  1. 我猜想/databases/schools/{schoolId}/的意思是根集合是schools而不是databases
  2. 您必须使用request.auth.token.schoolId才能通过用户的ID令牌检索自定义声明,请参见https://firebase.google.com/docs/auth/admin/custom-claims
  3. 在写入规则中使用request.resource.data.schoolId;,而不是resource.data.schoolId;

答案 1 :(得分:0)

感谢雷诺(Renaud)向我指出了正确的方向,终于在今天早上弄清楚了!也感谢这样的答案Recursive wildcards in Firestore security rules not working as expected

service cloud.firestore {
  match /databases/{database}/documents {
    match /schools/{schoolId} {
      allow read, write: if request.auth.token.schoolId == schoolId
    }

    match /schools/{schoolId}/{document=**} {
      allow read, write: if request.auth.token.schoolId == schoolId
    }
  }
}

似乎正在做我想要做的事情(我可以​​将==切换为!=,并且我的用户不再具有访问权限)