基于角色的访问权限控制
您可以利用 TCB 的数据模型以及自定义的安全规则,在您的应用中实现基于角色的访问权限控制。
假设您正在构建一款协作式撰文应用,用户可以按照以下安全要求在其中撰写“故事”和“评论”:
每个故事都有一名所有者,故事可共享给撰写者、评论者和读者。
- 读者:只能查看故事和评论,不能编辑任何内容。
- 评论者:除了拥有读者所拥有的全部访问权限之外,还可以就故事添加评论。
- 撰写者:除了拥有评论者所拥有的全部访问权限之外,还可以编辑故事内容。
- 所有者:可以编辑故事的任意部分,并且可以控制其他用户的访问权限。
数据结构
假设您的应用有一个 stories
集合,其中每个文档代表一个故事。
集合名称 | 说明 |
---|---|
comments 集合 |
每个文档代表一条针对该故事的评论 |
roles 集合 |
每个集合包含一个故事的用户的角色 |
roles 字段 |
将用户 ID 映射至角色 |
stories 集合
每一个story
文档数据数据如下:
{
id:"storyid"
title: "A Great Story",
content: "Once upon a time ..."
}
roles 集合
每一个role
文档数据数据如下:
{
id:"storyid"
roles: {
alice: "owner",
bob: "reader",
david: "writer",
jane: "commenter"
// ...
}
}
comments 集合
每一个comment
文档数据如下:
评论仅包含三个字段,留言者的用户 ID 、内容、storyid。
{
id:"xxx"
storyid:"storyid"
user: "alice",
content: "I think this is a great story!"
}
规则
数据库中记录用户角色,需要编写安全规则来进行角色验证。下列规则假定应用使用的是 TCB 身份验证,所以auth.uid
变量为用户 ID。
roles 添加规则
管理者可以更改角色,允许故事撰写者、评论者和所有者,读取角色。
{
"roles": {
"write": "doc.roles[auth.uid]==='owner' ",
"read": "doc.roles[auth.uid] in ['owner', 'writer', 'commenter', 'reader']"
}
}
stories 添加规则
管理者和故事撰写者可以更改故事,其它人可以读取故事。
{
"stories": {
"write": "get('/database/storyies/${id}').roles[auth.uid] in ['owner', 'writer'] ",
"read": "get('/database/storyies/${id}').roles[auth.uid] in ['owner', 'writer', 'commenter', 'reader'] "
}
}
comments 规则
- 允许故事撰写者、评论者和所有者发表评论。
- 只有评论的拥有者,可以更新评论。
- 拥有者和评论者可以删除评论。
{
"comments": {
"read": "get('/database/storyies/${id}').roles[auth.uid] in ['owner', 'writer', 'commenter', 'reader'] ",
"create": "get('/database/storyies/${id}').roles[auth.uid] in ['owner', 'writer', 'commenter', 'reader']",
"update": "doc.user == auth.uid",
"delete": "get('/database/storyies/${id}').roles[auth.uid] == ['owner'] || doc.user == auth.uid "
}
}
说明:
get
函数中id
是当前文档的 ID。后期可以通过请求的参数指定。此时开发者生成 ID 的时候需要谨慎,防止用户通过遍历 ID 访问数据,从而产生泄露。