MongoDB 的菜单权限必须由应用层控制,数据权限才由 RBAC 落地;菜单可见性、按钮状态、路由拦截均属前端或 API 层逻辑,而 MongoDB 角色仅管控数据库、集合级读写操作,不识别业务概念如“用户管理页”,且权限只增不减、不可动态降权。

菜单权限和数据权限必须分离设计,不能混在同一个角色里。MongoDB 本身不提供“菜单”概念,所谓菜单权限是业务层抽象,而数据权限才由 MongoDB 的 RBAC 真正落地。强行把前端菜单开关塞进数据库角色,会导致权限模型失焦、难以审计、无法动态控制。
菜单权限只能由应用层控制
菜单可见性、按钮启用状态、路由跳转拦截——这些全部属于前端或后端 API 层的逻辑判断,db.createUser() 或 rolesInfo 命令根本不认识“用户管理页”“订单导出按钮”这种东西。
- 前端根据登录用户返回的
role_code(如"admin"、"sales_viewer")做条件渲染,这个字段需由你的业务 API 提供,不是 MongoDB 自带 - 后端 API 在处理请求前,必须校验该用户是否具备访问当前接口的业务权限,比如
/api/v1/orders/export只允许role_code === "sales_exporter" - 不要试图用 MongoDB 的
read角色控制“能不能看到菜单”,它只管“能不能查orders集合”,两者语义完全不同
数据权限靠角色 + 资源粒度精准约束
MongoDB 的数据权限必须落到具体数据库、集合甚至字段级操作上,靠内置角色或自定义角色实现。关键不是“谁能看到菜单”,而是“谁能在哪个库的哪个集合执行什么操作”。
- 避免使用
readWriteAnyDatabase这类高危角色,哪怕给管理员也应限制为userAdminAnyDatabase+ 明确指定的业务库readWrite - 普通业务用户应按最小权限原则分配,例如销售专员只授
{ role: "readWrite", db: "sales_db", collection: "orders" }—— 注意:MongoDB 4.4+ 支持集合级角色,但需用createRole自定义,不能直接在createUser中写collection - 敏感字段(如用户手机号、身份证号)需配合应用层脱敏或 MongoDB 5.0+ 的
Queryable Encryption,RBAC 本身不支持字段级读写控制
多租户场景下必须用数据库隔离 + 角色绑定
如果你的系统要支持多个客户共用一套 MongoDB 实例(比如 SaaS),绝不能靠一个 customers 集合加 tenant_id 字段来软隔离——这会让数据权限完全依赖应用代码,一旦漏判就全库裸奔。
- 每个租户对应独立数据库(如
tenant_abc、tenant_xyz),创建用户时明确绑定db字段:{ role: "readWrite", db: "tenant_abc" } - 连接字符串中禁止硬编码数据库名,应用层必须根据用户上下文动态切换
use tenant_xxx,否则db.auth()认证会失败 - 禁用
localhost exception(即enableLocalhostAuthBypass: false),防止未授权用户直连 admin 库绕过租户隔离
最容易被忽略的一点:MongoDB 的角色继承是单向且不可撤销的。比如你给用户同时分配了 read 和 readWrite,撤掉 read 不会影响写权限;但如果你先给了 readWriteAnyDatabase,再补一个 read 到某个库,后者不会降权——权限只增不减,删错角色就只能重建用户。


















