MongoDB 6.0.7中api用户权限异常及Node.js应用认证失败排查
问题描述
我使用MongoDB 6.0.7,执行以下命令可正常通过api用户登录:
mongosh -u api -p --authenticationDatabase mydb_db
登录后可正常执行use mydb_db切换数据库,但执行db.getUsers()、show users时出现错误:
rs0 [direct: primary] mydb_db> db.getUsers() MongoServerError: not authorized on mydb_db to execute command { usersInfo: 1, lsid: { id: UUID("6bcc1743-9303-4ad4-a136-bc0b7bf0e1b8") }, $clusterTime: { clusterTime: Timestamp(1704272881, 1), signature: { hash: BinData(0, 62E80733C0FCF60FE333934D8E6796C319B16B99), keyId: 7264672765817389063 } }, $db: "mydb_db" } rs0 [direct: primary] mydb_db> show users MongoServerError: not authorized on mydb_db to execute command { usersInfo: 1, lsid: { id: UUID("6bcc1743-9303-4ad4-a136-bc0b7bf0e1b8") }, $clusterTime: { clusterTime: Timestamp(1704272881, 1), signature: { hash: BinData(0, 62E80733C0FCF60FE333934D8E6796C319B16B99), keyId: 7264672765817389063 } }, $db: "mydb_db" } rs0 [direct: primary] mydb_db> show dbs mydb_db 5.50 MiB
此外,使用相同凭据的Node.js应用连接数据库时,日志提示authentication failed。该数据库已正常运行数月,问题出现于修改api用户密码之后。
附.env文件内容:
NODE_ENV=production MONGO_URI_LOCAL=mongodb://localhost:27017/ MONGO_URI_SERVER=mongodb://api:myNewPassword@localhost:27017/ DB_NAME=mydb_db DB_USERNAME=api DB_PASSWORD=myNewPassword
排查与解决方案
一、权限异常处理
1. 确认用户权限配置
db.getUsers()和show users属于用户管理操作,需要当前用户拥有userAdmin(针对当前库)或userAdminAnyDatabase(全局)角色。普通业务用户默认不会分配这类权限,这是符合安全规范的。
若确实需要api用户具备查看用户列表的权限,需用管理员账号登录后执行授权:
# 用管理员账号登录(假设管理员账号在admin库) mongosh -u admin -p --authenticationDatabase admin # 切换到目标库 use mydb_db # 授予userAdmin角色 db.grantRolesToUser("api", [{ role: "userAdmin", db: "mydb_db" }])
2. 验证密码修改的有效性
修改密码时需确保在**认证数据库(即mydb_db)**下操作,避免出现密码不一致:
# 管理员登录后切换到mydb_db use mydb_db # 重新设置密码 db.changeUserPassword("api", "myNewPassword")
二、Node.js应用认证失败处理
1. 修正连接字符串的认证数据库
当前MONGO_URI_SERVER未指定authSource,MongoDB会默认使用test库作为认证源,但api用户的认证数据库是mydb_db,这是认证失败的核心原因。修改连接字符串:
MONGO_URI_SERVER=mongodb://api:myNewPassword@localhost:27017/mydb_db?authSource=mydb_db
2. 代码层面显式指定认证源(可选)
如果使用Mongoose等ODM,可在连接选项中明确指定认证数据库:
const mongoose = require('mongoose'); mongoose.connect(process.env.MONGO_URI_SERVER, { dbName: process.env.DB_NAME, authSource: process.env.DB_NAME // 绑定到mydb_db作为认证源 });
3. 清除应用缓存并重启
部分应用会缓存旧的数据库连接凭据,重启Node.js应用确保新密码生效。
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

