产品概述
功能和优势
应用场景
系统限制
json 来描述安全规则配置,示例配置如下:{"read": "auth.uid==doc.uid","write": "doc.name=='zzz'"}
json 配置的 key,是用户的操作类型,value 是一个表达式。当表达式执行结果的值是 true 的时候,用户的操作允许执行;否则,用户的操作则不被允许。操作类型 | 说明 | 默认值 |
read | 读文档 | false |
write | 写文档,可以细分为 create、update、delete | false |
create | 新建文档 | 无 |
update | 更新文档 | 无 |
delete | 删除文档 | 无 |
write 的规则。例如说开发者的安全规则配置如下:{"read": ".....","write": "....","create": "...."}
create 的对应规则,而 update 操作会读取 write 的规则。字段名 | 类型 | 说明 |
data | object | 请求数据,create,update 时存在,代表请求 data |
字段名 | 类型 | 说明 |
loginType | string | 登录方式,微信小程序过来的请求是没有此值的;web 登录下才有此值。 |
uid | string | 用户唯一 id,微信小程序的请求没有此值 |
openid | string | 用户 openid,仅在微信登录方式下存在值 |
枚举值 | 登录方式说明 |
WECHAT_PUBLIC | 微信公众号 |
WECHAT_OPEN | 微信开放平台 |
ANONYMOUS | 匿名登录 |
EMAIL | 邮箱登录 |
CUSTOM | 自定义登录 |
运算符 | 说明 | 示例 | 示例解释(集合查询) |
== | 等于 | auth.uid == 'zzz' | 用户的 uid 为 zzz |
!= | 不等于 | auth.uid != 'zzz' | 用户的 uid 不为 zzz |
> | 大于 | doc.age>10 | 查询条件的 age 属性大于 10 |
>= | 大于等于 | doc.age>=10 | 查询条件的 age 属性大于等于 10 |
< | 小于 | doc.age>10 | 查询条件的 age 属性小于 10 |
<= | 小于等于 | doc.age>=10 | 查询条件的 age 属性小于等于 10 |
in | 存在于集合中 | auth.uid in ['zzz','aaa'] | 用户的 uid 是['zzz','aaa']中的一个 |
!(xx in []) | 不存在于集合中,使用 in 的方式描述 !(a in [1,2,3]) | !(auth.uid in ['zzz','aaa']) | 用户的 uid 不是['zzz','aaa']中的任何一个 |
&& | 与 | auth.uid == 'zzz' && doc.age>10 | 用户的 uid 为 zzz 并且查询条件的 age 属性大于 10 |
|| | 或者 | auth.uid == 'zzz' || doc.age>10 | 用户的 uid 为 zzz 或者查询条件的 age 属性大于 10 |
. | 对象元素访问符 | auth.uid | 用户的 uid |
[] | 数组访问符属性 | get('database.collection_a.user')[auth.uid] == 'zzz' | collection_a 集合中 id 为 user 的文档,key 为用户 uid 的属性值为 zzz |
get(path: string): Document | null | undefined入参 | 类型 | 描述 |
path | string | 非空,格式为 database.集合名称.文档id 的字符串,值可以通过多种计算方式得到,例如使用字符串模版进行拼接:(database.${doc.collction}.${doc._id}) |
{"read": "get('database.test.123')[auth.uid] in [1,2,3]","delete": "get('xxxx')[auth.uid] == 1 && doc.user in ['ersed','sfsdf'] "}
{"read:": "auth.openid in get(`database.B.${doc.shopId}`).owner"}
3 个 get 函数,最多可以访问 10 个不同的文档。get(get(path))。get 会产生一次读操作,在使用变量时,每个 get,每个变量值会产生一次读操作,例如:规则 get(database.collection.${doc._id}).test,在查询 _.or([{_id:1},{_id:2},{_id:3},{_id:4},{_id:5}])} 下会产生 5 次读取。系统会对同 doc,同 field 的读取进行缓存。doc 条件指定单个文档 id。where 条件的查询或者是聚合搜索 match 限制条件的查询,如果是聚合搜索,只匹配第一个 match 限制条件。key 是 _openid 并且 value 是 {openid},或者 key 是 uid 并且 value 是 {uid},则在服务端自动将 value 替换为实际的值。doc 此时表示的是查询条件。这个子集是指规则上所有可能的子集,而不是实际数据的子集。read、update、delete。// colleciton_a 的安全规则的配置{"read":"doc.age>10"}// 符合安全规则let queryRes = db.collection('colleciton_a').where({age:_.gt(10)}).get()// 不符合安全规则let queryRes = db.collection('colleciton_a').where({age:_.gt(8)}).get// 符合安全规则let res = await db.collection('collection_a').aggregate().match({age: _.gt(10)}).project({age: 1}).end()// 不符合安全规则let res = await db.collection('collection_a').aggregate().match({age: _.gt(8)}).project({age: 1}).end()
id查询(需迁移改造)read、update、delete、create。create,会校验写入的数据是否符合安全规则的限制条件。read、update、delete,同时安全规则包含了 doc 的限制,则会先从 db 中读取一次文档数据,然后判断是否符合安全规则。update 操作,只会校验存在于数据库中已有的文档数据,不会对写入的数据进行校验;同时不保证这个操作的原子性。doc 操作(doc.get, doc.set 等)是仅指定 _id 进行的操作,其查询条件仅包涵 {_id:“xxx”},因此大部分情况下并不会满足安全规则的子集要求(除非在 "read": true 下进行读操作或在 "write": true 的情况下进行写操作),因此需要转换为等价的、查询条件包含安全规则或是其子集的形式。// colleciton_a 的安全规则的配置{"read":"doc._openid == auth.openid"}// 文档id='ccc'的数据是{age:12}// 不符合安全规则, 未满足子集需求let queryRes = db.collection('colleciton_a').doc('ccc').get()// 符合安全规则,改写为 where 查询let queryRes = db.collection('colleciton_a').where({_id: "ccc", _openid: "{openid}"}).get()
command | description |
or | || 逻辑或 |
and | && 逻辑与 |
command | description |
eq | == |
ne/neq | != |
gt | > |
gte | >= |
lt | < |
lte | <= |
in | in |
nin | !(in []) |
command | description |
set | 覆盖写,{key: set(object)} |
remove | 删除字段, {key: remove()} |
id 查询的所有写操作会产生一次数据访问。{"read": true,"write": "doc._openid == auth.openid" // 登录方式为微信"write": "doc._openid == auth.uid" // 登录方式为非微信}
{"read": "doc._openid == auth.openid" //登录方式为微信"read": "doc._openid == auth.uid" // 登录方式为非微信"write": "doc._openid == auth.openid" //登录方式为微信"write": "doc._openid == auth.uid" // 登录方式为非微信}
{"read": true,"write": false}
{"read": false,"write": false}
所有者;故事可共享给撰写者。撰写者除了拥有评论者所拥有的全部访问权限之外,还可以编辑故事内容。所有者可以编辑故事的任意部分,并且可以控制其他用户的访问权限。stories 集合,其中每个文档代表一个故事。还有一个 comments 集合,其中每个文档代表一条针对该故事的评论。一个 roles 集合,每个集合包含一个故事的用户的角色。为了跟踪访问角色,需要添加一个 roles 字段,用来将用户 ID 映射至角色:story 文档数据数据如下:{"id": `storyid`,"title": "A Great Story","content": "Once upon a time ..."}
role 文档数据数据如下:{"id": `storyid`,"roles": {"alice": "owner","bob": "writer","david": "writer"// ...}}
comment 文档数据如下,评论仅包含三个字段,留言者的用户 ID 、内容、storyid。{"id": `commentId`,"storyid": `storyid`,"user": "alice","content": "I think this is a great story!"}
{"write": "doc.roles[auth.uid] === 'owner' ","read": "doc.roles[auth.uid] in ['owner', 'writer']"}
{"read": true,"write": "get(`database.roles.${doc.id}`).roles[auth.uid] in ['owner', 'writer'] "}
{"read": true,"create": true,"update": "doc.user == auth.uid","delete": "doc.user == auth.uid "}
文档反馈