了解安全规则
安全规则语言
安全规则基于灵活、强大的自定义语言,能够支持各种复杂度和精细化程度的权限控制。开发者可以根据应用的具体需求,设置特定的规则或一般性的规则。安全规则使用 JSON 结构,其中:
key
指代操作类型(如读取、写入等)value
为允许操作的条件,可以是:- 简单的
boolean
值(true/false) - 类似 JavaScript 的表达式字符串
- 简单的
表达式可以是单个逻辑表达式,或通过与/或逻辑组合的多个表达式,系统会根据表达式的计算结果决定是否允许操作。
由于安全规则是专门设计的语言,可能需要一定的学习时间。本指南将帮助您理解规则语言的基础知识,为后续编写更复杂的规则打下基础。
基本结构与语法
- 数据库
- 云存储
- 云函数
安全规则基于 JSON 结构,value
为 boolean
或类似 JavaScript 的表达式:
{
"read": true,
"write": <<condition>>,
"create": true,
"update": false,
"delete": <<condition>>
}
其中包含几个关键概念
- 操作类型: JSON
key
为支持权限控制的操作类型,create
、delete
、read
、update
为集合的增删查改操作,write
为简便的控制集合的写权限配置,若没有配置create
、delete
、update
操作,则按照write
配置处理。 - 规则: JSON
value
为规则条件,可以为boolean
值或逻辑表达式(组),当条件值为 true 时表示允许进行操作。
默认情况下,遇到没有定义的操作类型,则拒绝该操作访问
安全规则基于 JSON 结构,value
为 boolean
或类似 JavaScript 的表达式:
{
"read": true,
"write": <<condition>>,
}
其中包含几个关键概念
- 操作类型: JSON
key
为支持权限控制的操作类型,read
、write
为云存储文件的读写操作。 - 条件: JSON
value
为规则条件,可以为boolean
值或逻辑表达式(组),当条件值为 true 时表示允许进行操作。
默认情况下,遇到没有定义的操作类型,则拒绝该操作访问
云函数安全规则基于 JSON 结构,层级较特殊,顶级 key
为表示函数名,value 为对应函数的权限配置,也为 JSON 格式,子配置 key
为操作名(invoke),value
为 boolean
或类似 JavaScript 的表达式:
{
"*": {
"invoke": "auth!==null"
},
"function1": {
"invoke": false
},
"function3": {
"invoke": true
}
}
其中包含几个关键概念
- 函数名: JSON 顶级
key
为函数名,用于匹配获取某个具体函数的配置,特殊的允许配置*
作为函数名的通配符,当没有匹配到具体函数时将获取*
的配置,云函数安全规则中必须包含*
配置。 - 操作类型: 函数名下子配置 JSON 的
key
为操作类型,暂只支持 invoke,且必须为 invoke。 - 条件: 子配置 JSON
value
为规则条件,可以为boolean
值或逻辑表达式(组),当条件值为 true 时表示允许进行操作。表达式只支持使用auth!=null
。
条件构造
条件可以为 boolean
或表达式字符串
,表达式字符串语法类似 Javascript 语言,其是单个逻辑表达式,或多个逻辑表达式通过与/或方式组合,当表达式的计算值决定了操作是否被允许。
- 数据库
- 云存储
- 云函数
预置变量
变量 | 类型 | 说明 |
---|---|---|
now | number | 当前时间戳,表示从 Linux 计时原点开始的毫秒数 |
auth | Auth | 用户登录信息,包含 uid(用户唯一ID)和 loginType(登录类型);未登录时为 null |
doc | Object | 当前操作的记录对象,引用时会从服务中读取一次,此查询会计入相关资源配额 |
request | Request | 请求对象,包含请求相关的各种信息 |
Auth
字段名 | 类型 | 说明 |
---|---|---|
loginType | string | 登录方式,如公众平台登录、开放平台登录、自定义登录、匿名登录等 |
uid | string | 用户唯一标识ID,注意:微信小程序请求中不包含此值 |
openid | string | 用户的微信openid,仅在微信相关登录方式下存在 |
LoginType 枚举值
枚举值 | 登录方式 |
---|---|
WECHAT_PUBLIC | 微信公众号 |
WECHAT_OPEN | 微信开放平台 |
ANONYMOUS | 匿名登录 |
邮箱登录 | |
CUSTOM | 自定义登录 |
Request
字段名 | 类型 | 说明 |
---|---|---|
data | object | 请求传入的数据对象,仅在 create 和 update 操作类型时存在 |
变量可用于规则表达式中,通过 doc
与 request.data
可以获取数据当前的值与请求传入的值。例如,在订单集合中,为防止订单金额被篡改,可使用以下规则:
{
// ... 其他规则 ... //
"update": "doc.price == request.data.price || request.data.price == undefined"
// ... 其他规则 ... //
}
这条规则确保:要么请求不修改价格字段,要么修改后的价格与原价格相同。
内置方法
目前仅支持 get 函数,该函数接受一个参数,格式必须为 database.集合名称.文档id
。通过此函数,您可以访问其它文档的数据,用于判断当前操作是否符合安全规则。
例如,检查用户是否有权限修改特定文档:
{
"update": "get(`database.users.${auth.uid}`).role == 'admin'"
}
预置变量
变量 | 类型 | 说明 |
---|---|---|
now | number | 当前时间戳,表示从 Linux 计时原点开始的毫秒数 |
auth | Auth | 用户登录信息,包含 uid(用户唯一ID)和 loginType(登录类型);未登录时为 null |
resource | Resource | 请求文件的元数据信息,引用时会从服务中读取一次 |
Auth
字段名 | 类型 | 说明 |
---|---|---|
loginType | string | 登录方式 公众平台登录,开放平台登录,自定义登录,匿名登录等等 |
uid | string | 用户唯一 id,微信小程序的请求没有此值 |
openid | string | 用户 openid,仅在微信登录方式下存在值 |
LoginType 枚举
枚举值 | 登录方式说明 |
---|---|
WECHAT_PUBLIC | 微信公众号 |
WECHAT_OPEN | 微信开放平台 |
ANONYMOUS | 匿名登录 |
邮箱登录 | |
CUSTOM | 自定义登录 |
Resource
字段名 | 类型 | 说明 |
---|---|---|
openid | string | 文件的私有归属标识,用于标记文件所有者ID |
path | string | 文件在云存储中的相对路径(不包含桶名),格式为 path/image.jpg ,注意:路径起始不包含 ./、/、. 等路径符 |
变量可用于规则表达式中,例如:设置 public 目录下的文件所有用户可读,但限制用户只能修改归属于自己的文件。
{
"read": "/^public\\//.test(resource.path) == true",
"write": "resource.openid == auth.uid"
}
这条规则确保:
- 所有以 "public/" 开头的路径中的文件对所有用户可读
- 用户只能修改自己创建的文件(文件所有者ID与用户ID匹配)
特殊方法
云存储安全规则支持特殊的正则表达式语法。您可以通过字面量方式引入正则对象(例如 /^reg\$/
),并通过调用正则对象的 test
方法来验证参数是否匹配该正则表达式。
在规则表达式中使用
test
方法时,必须显式地与true
或false
进行比较。例如:- 正确写法:
read: "/^public/.test(resource.path) == true"
- 错误写法:
read: "/^public/.test(resource.path)"
- 正确写法:
由于安全规则表达式存储在字符串中,正则表达式中的特殊字符需要进行多重转义:
- 例如,要匹配字符串
test/image
:- 正则对象本身为:
/^test\/image/
- 在规则表达式中应写为:
"/^test\\/image/.test(resource.path)"
- 正则对象本身为:
- 例如,要匹配字符串
转义规则:在JSON字符串中表示正则表达式时,反斜杠
\
需要写成\\
预置变量
变量 | 类型 | 说明 |
---|---|---|
auth | - | 云函数安全规则中,auth 只有 null 与非 null 两种状态,不支持访问 auth 的成员属性 |
运算符
运算符 | 说明 | 示例 | 含义说明 |
---|---|---|---|
== | 等于 | auth.uid == 'zzz' | 用户的 uid 等于 'zzz' |
!= | 不等于 | auth.uid != 'zzz' | 用户的 uid 不等于 'zzz' |
> | 大于 | a>10 | 变量 a 的值大于 10 |
>= | 大于等于 | a>=10 | 变量 a 的值大于等于 10 |
< | 小于 | a<10 | 变量 a 的值小于 10 |
<= | 小于等于 | a<=10 | 变量 a 的值小于等于 10 |
in | 存在于集合中 | auth.uid in ['zzz','aaa'] | 用户的 uid 是 ['zzz','aaa'] 中的一个值 |
!(xx in []) | 不存在于集合中 | !(auth.uid in ['zzz','aaa']) | 用户的 uid 不在 ['zzz','aaa'] 集合中 |
&& | 逻辑与(AND) | auth.uid == 'zzz' && a>10 | 用户的 uid 为 'zzz' 并且 a 值大于 10 |
|| | 逻辑或(OR) | auth.uid == 'zzz' || a>10 | 用户的 uid 为 'zzz' 或者 a 值大于 10 |
. | 对象属性访问符 | auth.uid | 访问 auth 对象的 uid 属性 |
[] | 对象属性或数组元素访问 | a[auth.uid] == 'zzz' | 对象 a 中键名为用户 uid 的属性值等于 'zzz' |