uniCloud 数据权限不能前端直连数据库,因为其权限控制仅支持集合粒度的静态开关,不支持字段级、行级或动态条件过滤,且权限配置必须在 DCloud 控制台手动设置,无法随用户身份实时变化。

uniCloud 数据权限为什么不能前端直连数据库?
因为 uni-app 前端调用 uniCloud.database() 时,实际请求会绕过云函数直接打到数据库服务层,而 uniCloud 的数据库权限控制是「全有或全无」的——你无法在前端代码里声明「只读 users 表的 name 和 avatar 字段」。哪怕你写了 collection('users').field('name,avatar').get(),只要后端没开对应权限,返回就是空数组或 permission denied 错误。
真正起作用的权限配置,只存在于 DCloud 控制台的「数据库」→「权限设置」页面里,且只能按集合(collection)粒度开关「读/写/新增/删除」,不支持字段级、行级或动态条件过滤。
- 前端直连数据库 = 所有用户共享同一套静态权限,无法区分角色
- 数据库权限开关必须手动在控制台操作,无法随登录用户实时变化
- 即使你用
where做简单过滤,比如.where({ uid: 'abc' }),若未开启「安全规则」或未启用 DB Schema,照样被拦截
云函数里怎么实现动态数据权限?
所有数据库操作必须封装进云函数,把权限逻辑从数据库层移到业务逻辑层。核心思路是:云函数接收用户身份(如 event.user 或 token 解析出的 role、deptId),再根据规则拼接查询条件。
例如查询订单列表,不同角色看到的数据不同:
// uniCloud/cloudfunctions/order-list/index.js
exports.main = async (event, context) => {
const db = uniCloud.database();
const { role, uid } = event.user || {};
let query = {};
if (role === 'admin') {
// 管理员看全部
} else if (role === 'warehouse') {
query.deptId = 'WH001'; // 限定仓库部门
} else if (role === 'sales') {
query.salesUid = uid; // 只看自己经手的
}
return db.collection('orders').where(query).get();
};
- 不要依赖前端传来的
where参数,防止恶意构造条件绕过权限 - 用户身份必须来自
event.user(由 uni-id 自动注入),而非前端传入的uid - 复杂权限场景建议引入 RBAC 模块,用
uniCloud.importObject('rbac')调用现成的hasPermission方法
DB Schema 和安全规则能替代云函数吗?
DB Schema 的「权限配置」和「安全规则」确实能做基础行级控制,比如设置 "read": "auth.uid == doc.uid",但它只支持简单表达式,不支持关联查询、多条件组合或外部服务校验(如查用户所属部门树)。一旦权限逻辑涉及跨表、缓存、API 调用或动态参数,就必须退回到云函数。
- Schema 权限适合「个人数据隔离」这类固定模式,比如用户只能读自己的 profile
- 但「财务部能看到所有华东区订单,且仅限已审核状态」这种复合条件,Schema 写不出来
- 安全规则里无法调用
uniCloud.database()或uniCloud.callFunction(),也没法读取 Redis 缓存 - 真要用 Schema,必须开启「强制校验」并在 collection 级别启用,否则前端仍可绕过
权限变更后如何让云函数立刻生效?
云函数代码本身是静态部署的,权限逻辑改了就得重新上传;但权限数据(如用户角色、部门归属)常变,不能每次改都发版。所以要把「权限判定依据」和「权限执行逻辑」拆开。
推荐做法:云函数内不硬编码角色映射,而是调用一个统一的权限服务:
// 在云函数中
const perm = await uniCloud.callFunction({
name: 'check-permission',
data: { action: 'order:list', target: 'all', uid: event.user.uid }
});
-
check-permission是个独立云函数,负责查用户角色、拉部门树、比对权限表,返回布尔值或过滤条件 - 权限表存在
permissions集合里,用action(如'order:export')作主键,方便后台管理界面修改 - 避免在每个业务云函数里重复写 if-else,也便于审计和灰度发布
最易被忽略的是缓存策略:权限数据查库频繁,建议用 uniCloud.getCache() 缓存 5–10 分钟,但用户角色变更时要主动 delCache,否则会出现「改了权限但看不到效果」的问题。


















