在我们日常的数据库管理工作中,MongoDB 作为一个灵活且强大的 NoSQL 解决方案,其 用户管理 机制始终是我们保障数据安全的最后一道防线。随着我们步入 2026 年,数据泄露和合规性要求变得更加严苛,仅仅知道“怎么查”已经不够了,我们需要从系统架构、自动化运维乃至 AI 辅助开发的角度来重新审视这些基础操作。
在本文中,我们将深入探讨 如何在 Mongo Shell 中列出所有用户,并在此基础上,结合 2026年的最新技术趋势(如 DevSecOps、AI 辅助编程)来分享我们在企业级项目中的实战经验。我们将通过丰富的概念解析和实战示例,带你从基础命令走向高级管理。
目录
核心基础:连接与权限上下文
在我们开始列出用户之前,让我们先确保环境是准备就绪的。你可能已经安装了 MongoDB,但在 2026 年的容器化部署和云原生环境中,连接数据库往往不再是简单的 mongo 命令。
让我们思考一下这个场景:你可能正通过 Kubernetes 集群内部的 Service 进行连接,或者正在使用 MongoDB Atlas 这样的云服务。此时,连接字符串通常包含身份验证信息。
// 现代开发环境中的标准连接方式
// 假设我们正在使用 Mongo Shell (mongosh) 而不是旧版的 mongo
// 1. 基础连接
mongo "mongodb://localhost:27017"
// 2. 带有认证和目标数据库的连接字符串(推荐)
// 注意:在生产环境中,密码绝不应硬编码,建议使用环境变量或 OCI Vault
mongo "mongodb+srv://:@cluster0.example.net/mydatabase?retryWrites=true&w=majority"
一旦进入了 Shell,请务必注意当前的 上下文。在 MongoDB 中,用户是定义在特定的 数据库 逻辑上下文中的。理解这一点至关重要,因为它决定了你执行 show users 时看到的结果。
// 切换到目标数据库
use mydatabase
// 此时,任何关于用户的操作都默认针对 ‘mydatabase‘ 数据库
1. 使用 Show 命令:快速审计之道
这是我们最常用的快速检查方式。让我们通过一个具体的例子来演练如何列出名为 mydatabase 的数据库中的用户。
基础操作示例
// 1. 连接到 MongoDB 并切换到 mydatabase 数据库
use mydatabase
// 2. 列出所有用户
show users
深入解析输出结果
当你运行上述命令后,Mongo Shell 会返回一个用户文档列表。在早期的版本中,这可能只是一个简单的列表,但在现代版本中,它包含了丰富的元数据。让我们来看一个典型的输出并进行详细解析:
{
"_id" : "mydatabase.user_admin",
"userId" : UUID("8cf6e0b8-1e05-4d34-884b-54dcd6b0b1cf"),
"user" : "user1",
"db" : "mydatabase",
"roles" : [
{
"role" : "readWrite",
"db" : "mydatabase"
}
],
"mechanisms" : [
"SCRAM-SHA-256"
],
"customData" : {
"employeeId": "EMP-2026-001",
"team": "Platform"
}
}
在 2026 年的生产环境中,我们特别关注以下几点:
- mechanisms (认证机制): 注意这里的 INLINECODEbec558f0。随着硬件性能的提升,我们应当淘汰旧的 INLINECODEd75d3b0e,全面转向 SHA-256 以增强安全性。如果在这个列表中看到 SHA-1,那就是一个需要立即修复的技术债务。
- customData (自定义数据): 这是一个经常被忽视的高级特性。我们可以利用这个字段存储审计信息,比如该用户对应的 HR 系统员工 ID。这在自动化运维和合规性检查中非常有用。
高级技巧:使用 Shell 脚本进行批量审计
在大型项目中,我们可能有数百个数据库。手动切换并检查是不现实的。让我们编写一个简单的 Shell 脚本逻辑,配合 show users 的返回特性,来批量检查权限。
// 批量检查多个数据库的用户数量(伪代码逻辑)
var dbList = ["sales", "marketing", "analytics", "logs"];
// 我们可以编写一个循环来快速审计
dbList.forEach(function(dbName) {
// 使用 getSiblingDB 避免切换当前的上下文环境
var db = db.getSiblingDB(dbName);
// 使用 programmatic API 便于脚本化
var users = db.getUsers();
print("[AUDIT] Database: " + dbName + " | User Count: " + users.length);
// 检查是否存在弱认证机制的用户
users.forEach(function(user) {
if (user.mechanisms && user.mechanisms.indexOf(‘SCRAM-SHA-1‘) >= 0) {
print(" [WARNING] User " + user.user + " is using weak SHA-1 auth!");
}
});
});
2. 使用 getUsers() 命令:编程式管理与过滤
INLINECODE910afbcd 命令虽然直观,但它本质上是 Shell 的语法糖,方便人类阅读。而在编写自动化脚本或需要更细粒度控制时,INLINECODE8fb8b337 方法才是我们的首选。
实战案例:查找特定角色的用户
假设我们需要在紧急情况下找出所有拥有 INLINECODEd0c6b2bd 权限的用户,以便进行权限回收审查。INLINECODEbdc37f0e 返回的是一个数组,这允许我们使用 JavaScript 的强大功能进行处理。
// 获取当前数据库的所有用户信息
var allUsers = db.getUsers();
// 使用 JavaScript 数组方法筛选出拥有管理权限的用户
var admins = allUsers.filter(function(user) {
// 检查 roles 数组中是否包含 ‘dbAdmin‘ 或 ‘root‘
return user.roles.some(function(role) {
return role.role === "dbAdmin" || role.role === "root";
});
});
// 输出结果
print("[SECURITY] Found " + admins.length + " privileged users:");
printjson(admins);
代码解析:
- db.getUsers(): 这个命令返回当前数据库的用户文档数组。与
show users不同,它的输出可以直接赋值给变量。 - Array.filter & Array.some: 这是现代 JavaScript 开发中处理数据的标准范式。我们使用 INLINECODE1e2b6532 遍历用户,并在内部使用 INLINECODE22486d1d 检查用户的 INLINECODEcd80e16d 数组。这比传统的 INLINECODE7f6aad81 循环更简洁,也更符合 Vibe Coding(氛围编程) 的理念——即让代码表达其意图,而不是让维护者去猜测逻辑。
2026 视角下的替代方案对比
INLINECODE1db7f08f
INLINECODE250669d2 (Admin)
:—
:—
快速人工查看,本地开发调试
全局用户管理,跨库查询
Shell 格式化输出
Cursor (游标)
低,无法编程处理
极高,支持复杂查询条件
viewUser
需要访问 admin 库的权限在我们最近的一个企业级重构项目中,我们明确规定了:人工交互使用 INLINECODE035f59e8,而所有 CI/CD 流水线中的检查必须使用 INLINECODE7f12946e 或直接查询 INLINECODE6eb7077e 系统集合,以确保输出的可解析性。
3. 高级实战:列出所有数据库的所有用户
这是很多初级教程未曾覆盖,但在实际生产环境中非常常见的需求。作为管理员,我们需要知道“集群层面”到底有哪些用户。
为什么我们需要全局视图?
假设你正在处理一个安全漏洞,你需要知道是否有任何异常用户被创建到了非业务数据库中。仅仅 use database; show users 是不够的,因为可能有数十个数据库。
解决方案:查询 admin 库
在 MongoDB 中,所有用户的信息实际上都集中存储在 INLINECODE7705227f 数据库的 INLINECODE7adfa0dc 集合中(这与每个数据库自己存储的视图不同,admin 库拥有全局视角)。
// 1. 切换到 admin 数据库
use admin
// 2. 直接查询 system.users 集合
// 这是一个低级别的操作,可以看到集群中所有的用户定义
// 注意:在生产环境中,请务必小心处理返回的敏感信息
db.system.users.find(
{},
{ "user": 1, "db": 1, "roles": 1, "mechanisms": 1, "_id": 0 }
).sort({ "db": 1, "user": 1 });
代码解析与最佳实践:
- Projection (投影): INLINECODE38a0de9e。请注意我们使用了投影。在生产环境中,INLINECODEd6764223 文档可能非常大(包含凭证、自定义数据等)。如果我们只想要看“谁”在“哪个库”,限制返回的字段可以极大地减少网络传输开销,这在跨云环境查询时尤为重要。
- Sort (排序): 按数据库和用户名排序,使输出结果更加整洁,便于后续的日志分析或 AI 代理阅读。
性能优化与监控:分页查询策略
在拥有数万用户的超大规模集群中,直接 find() 可能会带来性能抖动。我们建议采用 分页查询 策略,避免一次性加载过多数据到内存中。
// 高性能分页查询示例
var pageSize = 100;
var skip = 0;
var hasMore = true;
while (hasMore) {
// 获取用户,仅返回必要字段
var usersPage = db.system.users.find()
.projection({ "user": 1, "db": 1, "roles": 1 })
.sort({ "db": 1 })
.skip(skip)
.limit(pageSize)
.toArray(); // 在 Mongosh 中将游标转为数组
if (usersPage.length > 0) {
print("[PAGE " + (skip/pageSize + 1) + "] Fetched " + usersPage.length + " users.");
// 在这里执行批量处理逻辑,例如写入审计日志或发送到 SIEM
skip += pageSize;
} else {
hasMore = false;
}
}
4. 融合 AI 辅助开发:2026 年工作流
既然我们已经掌握了查询用户的命令,那么在 2026 年,我们如何将这些知识融入到由 AI 辅助的现代化开发流程中呢?
场景一:使用 Cursor/Windsurf 进行敏捷审计
想象一下,我们正在使用 Cursor 或 Windsurf 这样的现代 AI IDE。当我们需要编写一个复杂的用户审计脚本时,我们不再需要去翻阅官方文档的每一页。
我们的做法:
我们只需在编辑器中输入注释:
// TODO: 获取 Mongo 中所有拥有 ‘readWrite‘ 权限的用户,
// 并列出他们所在的数据库,按库名分组。
// 注意:排除 admin 数据库中的用户。
// 要求:使用 2026 推荐的 SCRAM-SHA-256 过滤逻辑。
然后,通过 IDE 内置的 AI(如 Copilot 或本地 LLM),我们可以瞬间生成基于 db.system.users.find 的聚合管道代码。这不仅节省了时间,更重要的是,AI 往往能记住那些我们不常用的复杂聚合语法,从而减少了因手动编写错误查询导致的生产事故风险。
场景二:Agentic AI 自动化修复
在 2026 年的 DevSecOps 理念中,安全左移 意味着我们在代码提交阶段就要发现问题。更进一步,我们可以利用 Agentic AI 在发现问题后自动尝试修复(在人工审核的前提下)。
我们可以编写一个 CI 流水线步骤,运行 Mongo Shell 脚本来检查“幽灵用户”或“弱认证用户”,并自动生成修复报告。
// 这是一个自动化安全检查脚本的片段,专为 CI/CD 设计
function auditUserSecurity() {
use admin;
// 查找所有仍在使用 SHA-1 的用户
// 这是 AI 推荐的查询模式,专门针对合规性检查
var weakAuthUsers = db.system.users.find({
"mechanisms": "SCRAM-SHA-1"
}, { "user": 1, "db": 1, "_id": 0 }).toArray();
if (weakAuthUsers.length > 0) {
print("[SECURITY ALERT] Found " + weakAuthUsers.length + " users using deprecated SHA-1:");
weakAuthUsers.forEach(function(u) {
print(" - " + u.db + "." + u.user);
});
// 在真实场景中,这里可以触发 Webhook 通知 Security Team
// 或者让 Agentic AI 尝试生成密码重置脚本
return 1; // 返回非0状态码导致 CI 失败
} else {
print("[SECURITY PASS] All users are using compliant authentication mechanisms.");
return 0;
}
}
// 执行审计
auditUserSecurity();
通过这种方式,我们将“列出用户”这一基础操作,上升到了 治理 的层面。这就是现代开发理念的核心:从数据中提取价值,从操作中提炼安全。
常见陷阱与边界情况
在我们的实战经验中,有几个陷阱是初级到中级工程师经常遇到的,让我们来逐一攻破:
- “隐身”的 Admin 用户: 你可能在 INLINECODE00c413a0 中执行了 INLINECODE575905c2,却没看到管理员账号。这是因为管理员账号通常定义在 INLINECODEb05a433b 数据库中。如果你想在特定数据库中给某个用户分配权限,请务必先 INLINECODE255004fb。
- 认证机制不匹配: 如果你刚刚将 MongoDB 从 4.x 升级到 6.x/7.x,可能会遇到用户无法登录的问题。请检查 INLINECODE1da9a7ab 中的 INLINECODEdade32c2 字段。如果你看到 INLINECODEbc6fc952,建议立即删除该用户并重建为 INLINECODEf3e5a2c2。
// 修复认证机制的示例
use admin
var oldUser = db.getUser("app_user");
if (oldUser) {
db.dropUser("app_user");
print("Dropped old user...");
}
// 使用 prompt 安全地输入密码
db.createUser({
user: "app_user",
pwd: passwordPrompt(),
roles: oldUser ? oldUser.roles : [ { role: "readWrite", db: "app" } ],
mechanisms: [ "SCRAM-SHA-256" ],
customData: { migratedAt: new Date() }
});
print("User recreated with SHA-256.");
- 权限不足: 当你尝试 INLINECODE5add5277 时收到错误:“not authorized on admin to execute command”。这意味着你当前的账号只有 INLINECODE1ac15fe8 权限,而没有 INLINECODE4678954a 或 INLINECODEc2cdaa3f 权限。你需要联系管理员为你添加相应的角色。
结论
总的来说,在 MongoDB Shell 中列出所有用户不仅仅是一个简单的查询操作,它是理解数据库安全态势的基石。从基础的 INLINECODEe8458f22 到系统级的 INLINECODEf2ce5fa8 查询,这些命令为我们打开了数据库治理的大门。
在 2026 年,随着技术的演进,我们不再仅仅满足于手动执行命令。我们结合了 AI 辅助开发、自动化审计脚本 以及 云原生架构 的理念,将这些基础操作转化为系统性的安全流程。希望本文不仅教会了你“如何列出用户”,更启发了你思考“如何更好地管理数据权限”。
让我们保持对技术的好奇心,在代码的海洋中继续探索!