数据权限管理
CloudBase 提供了多层次的数据权限管理机制,确保数据安全的同时满足不同业务场景的权限控制需求。
🎯 权限管理体系
CloudBase 数据权限管理包含三个层次:
权限类型 | 控制粒度 | 适用场景 | 配置复杂度 |
---|---|---|---|
基础权限控制 | 集合级别 | 简单的权限需求 | 低 |
安全规则权限 | 文档级别 | 复杂的业务逻辑 | 高 |
🔧 基础权限控制
配置方式
在 CloudBase 控制台 的 集合管理 页面,为每个集合设置对应的权限:
权限选项
从用户的身份出发,去选择对应的权限
权限类型 | 适用场景 |
---|---|
读取全部数据,修改本人数据 | 公开内容,如文章、商品 |
读取和修改本人数据 | 私人数据,如用户资料 |
读取全部数据,不可修改数据 | 配置数据,如系统设置 |
无权限 | 敏感数据,如财务信息 |
🛡️ 安全规则权限
功能概述
安全规则权限提供了更灵活、可扩展、更细粒度的权限控制能力,支持基于文档内容的动态权限判断。
核心特点:
- 文档级别控制:可以根据文档的具体内容决定访问权限
- 表达式驱动:使用类似编程语言的表达式定义权限逻辑
- 动态权限:支持基于用户身份、时间、数据内容的动态权限判断
- 仅限制 C 端:只限制客户端用户访问,不影响服务端(云函数)操作
配置入口
切换到「集合管理」页面,通过「安全规则权限」设置更精细的安全规则:
规则配置格式
安全规则使用 JSON 格式配置,基本结构如下:
{
"read": "表达式",
"write": "表达式",
"create": "表达式",
"update": "表达式",
"delete": "表达式"
}
操作类型说明
操作类型 | 说明 | 默认值 | 示例场景 |
---|---|---|---|
read | 读取文档 | false | 查询、获取文档 |
write | 写入文档(通用) | false | 当未指定具体写操作时的默认规则 |
create | 创建文档 | 继承 write | 新增数据 |
update | 更新文档 | 继承 write | 修改现有数据 |
delete | 删除文档 | 继承 write | 删除数据 |
💡 规则继承:如果没有指定具体的写操作规则(create/update/delete),会自动使用
write
规则。
表达式语法
全局变量
变量名 | 类型 | 说明 | 示例 |
---|---|---|---|
auth | Object | 用户登录信息 | auth.openid 、 auth.uid |
doc | Object | 文档数据或查询条件 | doc.userId 、 doc.status |
request | Object | 请求信息 | request.data |
now | Number | 当前时间戳 | now > doc.expireTime |
用户身份信息 (auth)
字段 | 类型 | 说明 | 适用场景 |
---|---|---|---|
openid | String | 微信用户 OpenID | 微信小程序登录 |
uid | String | 用户唯一 ID | Web 端登录 |
loginType | String | 登录方式 | 区分不同登录渠道 |
运算符支持
运算符 | 说明 | 示例 | 使用场景 |
---|---|---|---|
== | 等于 | auth.uid == doc.userId | 验证数据所有者 |
!= | 不等于 | doc.status != 'deleted' | 排除特定状态 |
>、>=、<、<= | 比较运算 | doc.age >= 18 | 数值范围判断 |
in | 包含于 | auth.uid in doc.editors | 检查用户是否在列表中 |
&& | 逻辑与 | auth.uid == doc.userId && doc.published | 多条件组合 |
|| | 逻辑或 | auth.uid == doc.userId \|\| doc.public | 多种访问方式 |
实际应用示例
1. 基础权限映射
所有用户可读,仅创建者可写:
{
"read": true,
"write": "doc._openid == auth.openid"
}
仅创建者可读写:
{
"read": "doc._openid == auth.openid",
"write": "doc._openid == auth.openid"
}
2. 复杂业务逻辑
文章发布系统:
{
"read": "doc.published == true || doc.author == auth.uid",
"create": true,
"update": "doc.author == auth.uid",
"delete": "doc.author == auth.uid && doc.published == false"
}
协作文档系统:
{
"read": "auth.uid in doc.readers || auth.uid in doc.editors || doc.owner == auth.uid",
"write": "auth.uid in doc.editors || doc.owner == auth.uid"
}
3. 时间控制
限时活动数据:
{
"read": "now >= doc.startTime && now <= doc.endTime",
"write": "doc.owner == auth.uid && now <= doc.endTime"
}
get 函数:跨文档权限验证
功能说明
get()
函数允许在权限验证时访问其他文档的数据,实现复杂的跨文档权限控制。
语法: get('database.集合名.文档ID')
使用示例
基于角色的权限控制:
{
"read": "get('database.user_roles.' + auth.uid).role in ['admin', 'editor']",
"write": "get('database.user_roles.' + auth.uid).role == 'admin'"
}
关联数据权限:
{
"read": "auth.uid == get('database.projects.' + doc.projectId).owner"
}
使用限制
- 单个表达式最多 3 个
get
函数 - 最多访问 10 个不同文档
- 嵌套深度最多 2 层
- 会产生额外的数据库读取操作(计费)
查询限制与优化
查询条件要求
安全规则要求查询条件必须是规则的子集:
// 安全规则
{
"read": "doc.age > 10"
}
// ✅ 符合规则(查询条件是规则的子集)
db.collection('users').where({
age: _.gt(15)
}).get()
// ❌ 不符合规则(查询条件范围更大)
db.collection('users').where({
age: _.gt(5)
}).get()
文档 ID 查询改造
传统的 doc().get()
查询需要改写为 where()
查询:
// ❌ 传统方式(不符合安全规则)
db.collection('posts').doc('postId').get()
// ✅ 改写后(符合安全规则)
db.collection('posts').where({
_id: 'postId',
_openid: '{openid}' // 使用模板变量
}).get()
最佳实践
1. 规则设计原则
- 最小权限原则:只授予必要的权限
- 明确性原则:规则表达式要清晰易懂
- 性能考虑:避免过多的
get()
函数调用
2. 常见模式
数据所有者模式:
{
"read": "doc._openid == auth.openid",
"write": "doc._openid == auth.openid"
}
公开读取,限制写入:
{
"read": true,
"write": "doc.author == auth.uid"
}
基于状态的权限:
{
"read": "doc.status == 'published' || doc.author == auth.uid",
"update": "doc.author == auth.uid && doc.status != 'locked'"
}
3. 调试技巧
- 使用简单的规则开始,逐步增加复杂度
- 在开发环境充分测试各种场景
- 注意查看控制台的权限错误信息
- 合理使用日志记录权限验证过程
🎯 权限选择指南
根据业务复杂度选择
业务场景 | 推荐方案 | 原因 |
---|---|---|
简单应用 | 基础权限控制 | 配置简单,满足基本需求 |
复杂业务逻辑 | 安全规则权限 | 灵活的表达式,支持复杂判断 |
企业级应用 | 角色权限 + 基础权限 | 组织架构支持,权限层次清晰 |
高安全要求 | 安全规则 + 角色权限 | 多层防护,精细控制 |
权限配置建议
- 从简单开始:先使用基础权限,根据需要逐步升级
- 分层设计:基础权限处理通用逻辑,安全规则处理特殊逻辑
- 测试验证:在开发环境充分测试各种权限场景
- 文档记录:详细记录权限设计思路和配置说明
通过合理的权限配置,您可以构建既安全又灵活的数据访问控制体系,满足各种复杂的业务需求。