作者:浪漫的白狼族 | 来源:互联网 | 2023-05-19 09:45
IntheFirebaseguides,oneoftherecommendationsistomaintainaninverseindextokeeptrackof
In the Firebase guides, one of the recommendations is to maintain an inverse index to keep track of user actions. Here's a snippet of what I'm referring to:
在Firebase指南中,建议之一是维护反向索引以跟踪用户操作。这是我所指的内容片段:
// An index to track Ada's memberships
{
"users": {
"alovelace": {
"name": "Ada Lovelace",
// Index Ada's groups in her profile
"groups": {
// the value here doesn't matter, just that the key exists
"techpioneers": true,
"womentechmakers": true
}
},
...
},
"groups": {
"techpioneers": {
"name": "Historical Tech Pioneers",
"members": {
"alovelace": true,
"ghopper": true,
"eclarke": true
}
},
...
}
}
Each user keeps track of his/her groups in an inverse index - meaning in this case, that the keys hold the real value, and the value doesn't matter.
每个用户在反向索引中跟踪他/她的组 - 在这种情况下,密钥保持实际值,并且值无关紧要。
Update
I wasn't sure how to update the index technically but I got it after a little research: the setValue
can take all manor of variables, not just key-value pairs. That means that updating an index is pretty simple: just get a reference to groups/$group_id/members/$member_id
and set its value to true
.
我不确定如何在技术上更新索引但我在经过一些研究后得到了它:setValue可以采用所有变量,而不仅仅是键值对。这意味着更新索引非常简单:只需获取groups / $ group_id / members / $ member_id的引用并将其值设置为true。
Now my question is different:
现在我的问题不同了:
Lets say all groups are private. Meaning users can join a group by invitation only - a current group member must add another user to the member list. So if I'm ghopper and I want to add alovelace as a member, I need to update her index which is part of her user object - which means I have to know her user ID somehow and have write access to her groups
field - and that seems like a security risk.
让我们说所有团体都是私人的。意味着用户只能通过邀请加入组 - 当前组成员必须将另一个用户添加到成员列表中。因此,如果我是ghopper并且我想添加alovelace作为成员,我需要更新她的索引,这是她的用户对象的一部分 - 这意味着我必须以某种方式知道她的用户ID并且具有对她的组字段的写入权限 - 以及这似乎是一种安全风险。
Any thoughts on how to manage this while keeping access as restricted as possible? Perhaps another DB object that maps a user known identifier, like an email to a group list?
有关如何管理这一点的任何想法,同时尽可能限制访问?也许另一个DB对象将用户已知的标识符(如电子邮件)映射到组列表?
1 个解决方案
1
Solution 1 - Client-side
解决方案1 - 客户端
One solution would be to have a separate user invitation object so that ghopper can add alovelace to the private group and have that show up alovelace's invitations instead of automatically adding her to the group. alovelace would then need to approve the addition and update her group membership. This way, only the user retains access to their user record. This is quite similar to adding friends on facebook, or requesting connections on linkedin.
一个解决方案是拥有一个单独的用户邀请对象,以便ghopper可以将alovelace添加到私人组并让其显示alovelace的邀请,而不是自动将她添加到组中。然后,alovelace需要批准添加并更新她的组成员资格。这样,只有用户才能保留对其用户记录的访问权限。这非常类似于在Facebook上添加朋友或在linkedin上请求连接。
For illustration, the schema could look something like this
为了说明,模式可能看起来像这样
// An index to track Ada's memberships
{
"users": {
"alovelace": {
"name": "Ada Lovelace",
// Index Ada's groups in her profile
"groups": {
// the value here doesn't matter, just that the key exists
// Only Ada can write here
"techpioneers": true,
"womentechmakers": true
}
},
...
},
"invitations": {
"alovelace": {
"name": "Ada Lovelace",
"groups": {
// the value here doesn't matter, just that the key exists
// Anyone can write here
"ghoppersfanclub": true, // Ada might accept this and move it to groups
"explicitcontentgroup": true, // Ada might reject this and delete this entry
}
},
...
},
"groups": {
"techpioneers": {
"name": "Historical Tech Pioneers",
"members": {
"alovelace": true,
"ghopper": true,
"eclarke": true
}
},
...
}
}
Solution 2 - Server-side
解决方案2 - 服务器端
Although Firebase is meant to enable building apps without server code, there are instances where you should get the server in the mix. In my opinon, security and the execution of trusted actions like one user making changes to another user's record (if we're not using a separate object like 'invitations' above) should be handled by your trusted server using the admin API. When ghopper adds alovelace as a member, one possible event sequence would be:
虽然Firebase旨在支持在没有服务器代码的情况下构建应用程序,但有些情况下您应该将服务器混合在一起。在我看来,安全性和可信操作的执行,例如一个用户对另一个用户的记录进行更改(如果我们没有使用上面的“邀请”之类的单独对象)应由您的可信服务器使用admin API处理。当ghopper添加alovelace作为成员时,一个可能的事件序列将是:
- Check that ghopper belongs to the group and can add another user (client-side)
检查ghopper是否属于该组,并可以添加另一个用户(客户端)
Send a request to your server with payload that includes group name/id, user sending the request and email of the user being added
向您的服务器发送请求,其中包含有效负载,包括组名/ ID,发送请求的用户以及正在添加的用户的电子邮件
Server then looks up alovelace's user id using the provided email and update the user record.
然后,服务器使用提供的电子邮件查找alovelace的用户ID并更新用户记录。
admin.auth().getUserByEmail(alovelace_email)
.then(function(userRecord) {
// Add group to alovelace's groups.
// Trigger a client-side notification using child_changed
// Allow alovelace to approve or decline addition to group
})
.catch(function(error) {
console.log("Error fetching user data:", error);
});
The above example uses email as a public/shareable unique identifier, but there's also a similar getUserByPhoneNumber(phoneNumber) method.
上面的示例使用电子邮件作为公共/可共享的唯一标识符,但也有类似的getUserByPhoneNumber(phoneNumber)方法。