ral*_*r80 2 firebase firebase-security google-cloud-firestore
用例摘要
注意:故事只能被分享给谁或由谁创建
我正在构建一个基于角色的访问系统。我一直在查看基于角色的访问 firestore 文档,但我遗漏了一件。
考虑一个故事,该故事只能由已共享该故事的用户阅读。大多数示例包括 firestore 示例使用UIDhas 密钥来识别共享用户。但是,该用户当前可能不是 firebase 应用程序的用户,另外用户如何分配该 UID。
故事数据
{
title: "A Great Story",
roles: {
aliceUID: {
hasRole: true,
type: "owner",
},
bobUID: {
hasRole: true,
type: "reader",
}
}
}
Run Code Online (Sandbox Code Playgroud)
故事查询
firebase.firestore().collection('stories').where(`roles.${user.uid}.hasRole`, '==', true)
Run Code Online (Sandbox Code Playgroud)
第二部分可能通过维护一个单独的用户集合来解决,然后您可以从他们的电子邮件地址中找到用户,但这并不能解决从未登录过的用户。
打算分享故事的用户可以添加具有电子邮件地址的用户。然后使用 firebase 函数,我们可以发送电子邮件通知用户共享故事,用户可以登录应用程序并阅读该故事。
如果我们继续使用这种方法,那么您将没有 UID,而只有一个电子邮件地址作为密钥。
故事数据
{
title: "A Great Story",
roles: {
alice@yahoo.com: {
hasRole: true,
type: "owner",
},
bob@gmail.com: {
hasRole: true,
type: "reader",
}
}
}
Run Code Online (Sandbox Code Playgroud)
故事查询
firebase.firestore().collection('stories').where(`roles.${user.email}.hasRole`, '==', true)
Run Code Online (Sandbox Code Playgroud)
更新的 Firestore 规则- 来自文档
function getRole(rsc) {
// Read from the "roles" map in the story document.
return rsc.data.roles[request.auth.uid] || rsc.data.roles[request.auth.token.email];
}
Run Code Online (Sandbox Code Playgroud)
我无法使电子邮件查询工作。这个SO问题提到
不幸的是,点不允许作为地图键。所以电子邮件地址将不起作用。
我不明白为什么这会在规则方面产生冲突。它确实会导致一个可能无效的 where 子句
例如
.where(`roles.${user.email}.hasRole`, '==', true) -> .where(`roles.bob@gmail.com.hasRole`, '==', true)
Run Code Online (Sandbox Code Playgroud)
这看起来像无效的 JS 并且不幸的是[并且]是无效的字符所以我们不能这样做
.where(`roles[${user.email}]hasRole`, '==', true)
Run Code Online (Sandbox Code Playgroud)
我在这个Firebase 演讲中看到的最后一件事是使用类似的东西来转义电子邮件地址
function encodeAsFirebaseKey(string) {
return string.replace(/\%/g, '%25')
.replace(/\./g, '%2E')
.replace(/\#/g, '%23')
.replace(/\$/g, '%24')
.replace(/\//g, '%2F')
.replace(/\[/g, '%5B')
.replace(/\]/g, '%5D');
};
Run Code Online (Sandbox Code Playgroud)
这似乎修复了查询where子句,它是一个有效的数据结构,但它不是一个有效的 Firestore 规则,这意味着它没有真正的安全实施。
关于如何实现这一点的任何想法?请包括有效的数据结构、firestore 规则和查询。我已经展示并看到了许多示例,其中三个示例中的两个都是无效的解决方案。
谢谢!
基本问题是我不知道如何正确地制定有效的查询。事实证明,您不需要在一行中创建查询。
您可以使用FieldPath来构造您的查询参数。
var path = new firebase.firestore.FieldPath('roles', email ,'hasRole');
firebase.firestore().collection('stories').where(path, '==', true)
Run Code Online (Sandbox Code Playgroud)
这解决了原始丢失的部分。
| 归档时间: |
|
| 查看次数: |
2090 次 |
| 最近记录: |