not authorized 错误常因角色绑定数据库与操作数据库不匹配所致,而非单纯权限不足;需检查 authSource 是否与用户创建库一致,并用 connectionStatus 验证实际权限。

为什么 not authorized on db to execute command 不一定是账号没权限
这个错误常被当成“账号权限不够”,但实际更可能是角色绑定范围不对。MongoDB 的权限是「数据库级」和「集群级」分离的,比如你用 db.createUser() 给用户分配了 readWrite 角色,但指定在 admin 库,而实际操作的是 myapp 库——这时连 show collections 都会报这个错,因为权限没覆盖到目标库。
- 角色必须显式绑定到操作所用的数据库(或用
clusterAdmin等全局角色) -
admin库里的用户 ≠ 对所有库都有权限;它只是用户元数据存放地 - 连接时认证库(
--authenticationDatabase或 connection string 中的authSource)和操作库必须匹配权限范围,否则权限不生效
快速验证权限是否真的缺失:用 db.runCommand({connectionStatus: 1})
这个命令能直接返回当前会话的实际权限列表,比猜更可靠。它不触发权限检查,只要能连上就能执行,结果里 authInfo.authenticatedUserRoles 是关键。
- 如果返回空数组,说明根本没认证成功(检查
authSource是否写错) - 如果角色存在但没包含目标库名(如只有
{role: "readWrite", db: "admin"}),那对test库的操作必然失败 - 注意:该命令必须在目标库上下文中运行,比如
use myapp; db.runCommand(...),否则可能返回默认库的权限视图
修复权限最稳妥的做法:用 db.grantRolesToUser() 补权限,别删重建
直接改用户文档风险高,容易丢配置;grantRolesToUser 是原子操作,支持叠加,适合线上补救。
- 给用户
myuser在myapp库加读写权限:use myapp db.grantRolesToUser("myuser", [{role: "readWrite", db: "myapp"}]) - 如果要跨库查(比如聚合时 $lookup 到其他库),得单独为每个涉及库授对应角色
- 避免用
db.updateUser()直接覆写 roles 字段——它会清掉原有角色,除非你确认要重置 - 新用户创建时,务必在目标库下运行
db.createUser(),而不是只在admin下建
连接字符串里 authSource 写错是最隐蔽的坑
很多工具(如 Compass、Node.js driver)默认把 authSource 当成 admin,但如果你的用户是在 myapp 库创建的,连接时却指定 authSource=admin,MongoDB 就去 admin 库找用户记录——找不到,于是降级为匿名会话,自然报权限错。
- 检查用户在哪建的:
use myapp db.getUser("myuser")——看user字段和db字段是否一致 - 连接字符串应匹配:若用户在
myapp库,则用mongodb://u:p@h:27017/myapp?authSource=myapp - Driver 初始化时也要显式传
authSource,Node.js 里是auth: { authSource: "myapp" }
权限模型本身不复杂,但 MongoDB 把「用户存哪」和「权限管哪」拆成两个维度,又默认引导人往 admin 上堆,这就让错配成了高频问题。每次遇到这个错,先跑一遍 connectionStatus,再盯住 authSource 和角色里的 db 字段是否对得上——90% 的 case 都卡在这两处。










