通过哪里无法通过uid保护收集文档

时间:2020-04-16 23:26:48

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

在我的应用程序中,一旦用户通过Firebase身份验证登录,我想从我的Firestore数据库中获取其他数据。

我不希望用户能够查看其他用户的文档,因此我为此创建了一条规则:

pipeline {
        agent any

        environment {
            EMAIL_INFORM = 'abc@gmail.com;def@gmail.com'
        }


        stages {
        }

        post {

            success {  
                emailext body: 'Check console output at $BUILD_URL to view the results.', 
                        to: "${EMAIL_INFORM}", 
                        subject: 'Jenkins - Released $PROJECT_NAME - #$BUILD_NUMBER'
            }

        }
    }

在我的脑海中,我写的理论上应该允许当前登录的用户仅查看有关他自己的数据,并且在“规则游乐场”中可以正常工作。

但是,当我在应用程序中尝试此代码时,出现错误:match /users/{userId} { function isAuthenticated() { return request.auth != null; } function userIsSelf() { return request.auth.uid == userId; } allow read: if isAuthenticated() && userIsSelf(); }

我认为这与Firestore提取数据的方式有关吗?

我查询此问题的方式是使用FirebaseError: Missing or insufficient permissions.获取集合users,该集合仅返回uid与登录用户相同的用户:

where

我创建了Firestore规则,如下所示:

const querySnapshot = await firebase.firestore().collection("users").where("uid", "==", uid).get().catch(err => {
    console.error('could not fetch user', err)
})

if (!querySnapshot || querySnapshot.empty) {
    dispatch('logout')
    throw new Error('Cannot find logged in user\'s data in database')
} 

const userData = querySnapshot.docs[0].data()
commit('setUser', userData)

1 个答案:

答案 0 :(得分:2)

您的查询与您的规则不符。您的查询正在尝试获取uid字段与提供的uid匹配的所有文档:

firebase.firestore()
    .collection("users")
    .where("uid", "==", uid)

但是您的规则是说,用户只能使用其UID匹配的ID访问个人文档。该规则将每次都拒绝此查询,因为它根本不查看文档ID,而只是查看字段。

您的规则允许该查询代替:

firebase.firestore()
    .collection("users")
    .doc(uid)

如果您确实希望允许用户访问其UID与文档中的uid字段匹配的任何文档,则需要像这样调整它们:

match /users/{userId} {
  function isAuthenticated() {
    return request.auth != null;
  }

  function checkDocUid() {
    return request.resource.data.uid == request.auth.uid;
  }

  allow read: if isAuthenticated() && checkDocUid();
}

请注意,request.auth.uid是经过身份验证的用户的uid,request.resource.data.uid是文档中uid字段的值。

始终记住,您的查询必须与规则完全匹配,并且security rules are not filters