核心是角色层级、数据权限、操作权限在云函数、数据库规则和前端逻辑中对齐;需用云函数封装角色继承校验,数据库规则调用其判断,云函数动态拼装查询条件实现上下级数据访问,前端路由与ui权限均源自服务端统一返回的权限列表。

uni-app 结合 uniCloud 实现多级角色权限控制,核心不是“加个判断就行”,而是要让角色层级、数据权限、操作权限三者在云函数、数据库规则和前端逻辑中对齐。静态写死的 if (role === 'admin') 会迅速失控,尤其当出现“区域经理→下属门店店长→收银员”这类嵌套关系时。
uniCloud 数据库安全规则如何支持角色继承
数据库层面必须用 match + auth + 自定义函数组合,不能只靠 auth.role === 'admin' 这种扁平判断:
- 在
database/xxx/xxx.rule.json中,用get()调用云函数查用户完整角色链,例如:get(/userRoles/$uid).data.roles返回['region_manager', 'store_manager'] - 把角色继承逻辑封装进云函数(如
checkRoleInheritance),输入当前用户角色和目标资源所属组织 ID,输出布尔值;数据库规则里用callFunction调用它 - 避免在规则里写复杂逻辑——安全规则执行有严格超时(默认 1s)和表达式限制,嵌套
get()超过 2 层极易超时
云函数里怎么处理“上级能看下级数据”这类权限
关键在于查询条件动态拼装,而不是靠后端硬编码过滤:
- 前端传参只带基础筛选项(如
page=1,size=20),不传orgId或storeId这类敏感字段 - 云函数内通过
uniCloud.getDB().collection('user').doc(event.userInfo.uid)查出当前用户角色和所属组织树(比如缓存在user.orgPath = '1/5/23') - 再用
db.collection('order').where({ orgPath: { $regex: '^' + user.orgPath } })实现“本级及所有下级”数据拉取 - 注意:
$regex在阿里云 MongoDB 版本需开启全文索引,否则性能极差;腾讯云则建议用数组字段 +$in配合预计算的allSubOrgIds: [1,5,23,24,25]
前端路由守卫如何避免“看到但打不开”的体验
uni-app 的 onLaunch 和 onShow 里做权限校验,但必须配合服务端返回的可访问路由列表,而非仅依赖本地存储的角色字符串:
- 登录成功后,调用云函数
getAccessibleRoutes,传入event.userInfo.uid,返回类似['/pages/dashboard', '/pages/orders', '/pages/stores/edit']的数组 - 把这个数组存入
uni.setStorageSync('allowedRoutes', ...),并在router.beforeEach中比对to.path - 特别注意:H5 端可被直接 URL 访问,必须在云函数里做二次校验;小程序端也要防调试工具篡改本地 storage
- 不要用
v-if="hasPermission('order:edit')"控制按钮,而应从allowedRoutes或接口返回的actionList中取真实权限标识
真正难的不是写几个 if,而是让数据库规则、云函数、前端路由、UI 组件四层权限判断都基于同一份角色-资源映射关系,并且支持运行时变更。一旦某一层绕过校验(比如前端没校验路由,或数据库规则漏掉某个 collection),整个权限体系就形同虚设。











