编写安全规则
安全规则允许您控制数据的访问权限。通过灵活的规则语法可以在集合或存储桶上实现不同粒度的读写控制组合。
默认规则
默认情况下,安全规则拒绝所有的数据访问。
{}
用户身份认证
经过身份认证的用户发起请求时,系统会使用用户唯一 id uid
及用户登录方式 loginType
填充 auth
变量。当未经身份验证的用户发出请求时,auth
变量值为 null
。
通过 auth
变量,可以用以下常用方式来根据身份对文件访问进行控制:
- 公开:不判断
auth
值。 - 只对已登录用户公开:检查
auth
不为null
。 - 用户私有:检查
auth.uid
是否等于资源openid
。 - 仅对某种特殊的登录方式进行判断,限制匿名登录用户访问,检查
auth.loginType
不为ANONYMOUS
公开
任何不考虑 auth
的规则均可被视为 public
规则,因为他不考虑用户的身份验证上下文,这些规则在呈现公开数据(静态资源内容)的场景下是很适用。
- 云数据库
- 云存储
{
"read": "doc._openid != null"
}
{
"read": "resource.openid != null"
}
对登录的用户开放
在某些情况下,您可能希望限制只有登录用户在可以访问用户数据。例如,登录用户才可以查看论坛中的讨论。由于所有未登录用户的 auth
变量为 null
,因此可以设置如下规则:
{
"read": "auth != null"
}
所有用户可读,仅创建者及管理员可写
- 云数据库
- 云存储
数据通过 _openid 记录当前数据的归属用户 ID
{
"read": true,
"write": "doc._openid == auth.openid", // 登录方式为微信
"write": "doc._openid == auth.uid" // 登录方式为非微信
}
{
"read": true,
"write": "resource.openid == auth.openid", // 登录方式为微信
"write": "resource.openid == auth.uid" // 登录方式为非微信
}
仅创建者及管理员可读写
- 云数据库
- 云存储
数据通过 _openid 记录当前数据的归属用户 ID
{
"read": "doc._openid == auth.openid", //登录方式为微信
"read": "doc._openid == auth.uid", // 登录方式为非微信
"write": "doc._openid == auth.openid", //登录方式为微信
"write": "doc._openid == auth.uid" // 登录方式为非微信
}
{
"read": "resource.openid == auth.openid", //登录方式为微信
"read": "resource.openid == auth.uid", // 登录方式为非微信
"write": "resource.openid == auth.openid", //登录方式为微信
"write": "resource.openid == auth.uid" // 登录方式为非微信
}
所有用户可读,仅管理员可写
{
"read": true,
"write": false
}
仅管理员可读写
{
"read": false,
"write": false
}
数据验证
您可以根据数据库或存储分区中的现有数据,使用安全规则有条件地写入新数据。您还可以编写用来强制执行数据验证的规则,方法是根据写入的新数据来限制编写操作。
对新数据的限制
- 云数据库
- 云存储
如果要确保包含特定字段的文档尚未创建。例如,如果要拒绝创建包含 ranking 字段的所有文档,您可以在 create 条件中禁止它。
{
// ... //
"create": "request.data.ranking == undefined"
}
上传的文件都必须有归属值,且归属当前用户。
{
// ... //
"write": "resource.openid == auth.openid"
}
使用现有数据
许多应用都将访问权限控制信息以字段形式存储在数据库中的文档内。安全规则可以根据文档数据属性控制访问:
要实现此权限控制,需要在用户数据中定义对应的属性。安全规则根据数据属性检查请求,校验允许或拒绝。例如,我们再存储成绩,则可以向不同的用户组分配不同的访问权限级别:向“学生”组分配内容只读权限,向“教师”组分配教师所教科目的读写权限.用户表(user 集合)则可以设计如下结构:
{
userID: string, // 用户唯一id
role: string, // STUDENT, TEACHER,
projects: string[] // 教师所教科目
}
成绩表(score)设计如下:
{
studentID: string,
project: string,
score: number
}
成绩表规则可设置为:
{
"read": "get(`database.user.${auth.uid}`).role == 'STUDENT' || (get(`database.user.${auth.uid}`).role == 'TEACHER' && doc.project in get(`database.user.${auth.uid}`).projects)",
"write": "get(`database.user.${auth.uid}`).role == 'TEACHER' && doc.project in get(`database.user.${auth.uid}`).projects"
}