firebase Cloud Firestore的安全规则-用户只能访问自己的文档

rjee0c15  于 2022-12-30  发布在  其他
关注(0)|答案(1)|浏览(147)

我有一个users集合,下面的规则显然有效:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

以下两个代码段不允许访问,但我不知道为什么:

// Fails:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if database == "users"
    }
  }
}

//Fails:

rules_version = '2';
service cloud.firestore {
  match /{collectionName}/{documentId} {
    allow read, write : if collectionName == "users";
  }
}

我正在查看this,并希望得到如下代码:

rules_version = '2';
service cloud.firestore {
  match /users/{userId} {
    allow read: if request.auth.uid == userId;
  }
}

但是这也失败了,我显然没有抓住重点,我怎么才能只允许用户访问他们的文档呢?

编辑

下面是我的前端代码在我的Vuex商店:

async getUserData ({ commit }) {
  const querySnapshot = await getDocs(collection(db, 'users'))
  querySnapshot.forEach((doc) => {
    console.log(`${doc.id} => ${JSON.stringify(doc.data())}`)
  })
},

正如我提到的,这将立即打印(所有)个用户。例如,每个用户的如下内容:

Z9FiUutcAIVnXXXXXXXX => {“machineIds”:{“latest":"a","a":"M6021C67FA","b":"M6021C67FA"},"email":"dave@domain.co.uk","unlock”:”XXX”}

现在,我只需要访问已登录的用户,如前所述。
所以我玩了一下,这个“作品”(实际上打印所有记录):

// Works:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{collectionName}/{documentId} {
      allow read, write : if collectionName == "users";
    }
  }
}

但这些函数不成立,并给予Uncaught (in promise) FirebaseError: Missing or insufficient permissions.

// Fails:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read: if request.auth.uid == userId;
    }
  }
}

// Fails:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{email} {
      allow read: if request.auth.token.email == email;
    }
  }
}

我尝试了第二种方法,希望它能工作,因为我的数据结构是这样的,没有userId
下面是我的数据结构:

我也玩了一点周围的Rules Playground无济于事。
我觉得非常尴尬,因为我知道我做错了什么,解决办法是超级简单的。任何帮助将是梦幻般的。

kuarbcqp

kuarbcqp1#

记住安全规则不是过滤器是很重要的。安全规则不会改变查询的结果--它们只是根据您定义的条件允许或拒绝查询。客户机代码请求users下的所有文档,查询的结果要么是所有内容,要么是一个错误,指出不允许他们拥有所有内容。
如果用户只能获取他们自己的文档,您需要在查询中添加一个过滤器,以仅请求这些文档,并检查规则中的过滤器是否正确。通常情况下,人们使用Firebase Auth UID作为存储在文档或其ID中的值,以确定该用户是否可以使用它。
你也应该知道match表达式只会查看文档的路径和文档名。它们不像你尝试的那样匹配文档的字段。如果你想让用户只能够获取他们的Firebase Auth电子邮件地址为某个值的文档,那么你的规则应该如下所示:

match /databases/{database}/documents {
    match /users/{id} {
      allow read: if request.auth.email == resource.data.email;
    }
  }

您可能需要花些时间来了解resource在查询中的作用。“基于字段保护和查询文档”文档将有所帮助。
有了这个规则,现在您的客户端应用的查询需要在email上使用其auth电子邮件字符串的确切值进行过滤(只有在使用电子邮件/密码auth时才能保证存在)。

相关问题