【问题标题】:Matching custom claims with firestore document id将自定义声明与 Firestore 文档 ID 匹配
【发布时间】:2018-10-08 05:34:32
【问题描述】:

我的数据大致如下:

/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"

【问题讨论】:

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


    【解决方案1】:

    以下应该有效:

    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;

    【讨论】:

    • 这似乎没有做到。当我粘贴规则时,它抱怨格式错误,所以我将第 4 行更改为 match /schools/{schoolId} { 但我仍然被拒绝许可。我也没有在您发布的文档中看到任何提及资源一词。
    【解决方案2】:

    今天早上终于弄明白了,感谢 Renaud 为我指明了正确的方向!还要感谢这个 SO 回答 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
        }
      }
    }
    

    似乎正在做我想做的事(我可以切换 == 等于 != 并且我的用户不再有访问权限)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-07
      • 2019-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多