简介
管理用户和身份验证是管理 MongoDB 服务器时最重要的管理任务之一。您必须确保服务器配置正确,能够正确识别您的用户和应用程序,并拒绝无法正确进行身份验证的连接或操作。
为了管理这些需求,您必须能够决定服务器需要哪些用户,并创建这些帐户。作为此过程的一部分,您可以设置身份验证详细信息,以允许使用新身份进行外部访问。
在本指南中,我们将逐步介绍如何创建、查看和删除用户帐户。我们将介绍如何为您的帐户设置身份验证,以及如何在需要更改用户密码时更新凭据。
如果您正在使用 MongoDB,请查看 Prisma 的 MongoDB 连接器!您可以使用 Prisma Client 自信地管理生产 MongoDB 数据库。
要开始使用 MongoDB 和 Prisma,请查看我们的 从零开始入门指南,或如何添加到现有项目。
先决条件
要学习本指南,您需要在 MongoDB 服务器上拥有一个具有适当权限的帐户。
我们将使用的命令和方法
要在 MongoDB 中创建、修改和删除用户以及配置身份验证,您需要使用的核心方法是
db.createUser
:创建一个新的 MongoDB 用户帐户db.updateUser
:更新用户帐户的详细信息db.changeUserPassword
:更改用户帐户使用的密码db.dropUser
:删除 MongoDB 用户帐户
此外,以下数据库命令对于查找系统中有关用户的信息非常有用
db.runCommand('usersInfo')
:显示一个或多个 MongoDB 用户帐户的信息
所需权限
要执行上述命令,您需要使用具有许多不同权限操作的帐户登录 MongoDB。您需要的具体权限取决于您需要使用的命令。
要获取有关其他用户的信息,您当前的用户必须启用以下权限操作
要创建新用户,您当前的用户必须启用以下权限操作
要更改用户的密码或帐户详细信息,您可能需要以下权限
changeOwnPassword
权限操作 以更改您自己的帐户密码changeOwnCustomData
权限操作 以更改您自己的帐户的自定义数据changePassword
权限操作 以更改其他用户的密码changeCustomData
权限操作 以更改其他用户的自定义数据
本指南不涉及角色管理,因此不需要 grantRole
和 revokeRole
权限操作。
要删除用户帐户,您当前的用户必须启用以下权限操作
了解 MongoDB 如何实现用户和身份验证
在我们开始创建和管理帐户之前,花一些时间熟悉 MongoDB 如何定义和存储此信息会很有帮助。
在 MongoDB 中,用户帐户是帐户用户名和特定的身份验证数据库的组合。身份验证数据库只是定义用户的数据库,并不意味着范围或权限的限制。身份验证数据库是用于管理其他数据的常规数据库,而不是特殊的专用数据库。
用户帐户名在其身份验证数据库中必须是唯一的。但是,相同的用户名可以与不同的身份验证数据库重用,以创建新的、不同的用户帐户。
由于这种设计,只能通过包含用户名和身份验证数据库来准确识别帐户。要验证帐户身份,还需要能够提供与帐户关联的凭据。这通常是密码,但也可是证书。
如何创建用户?
现在我们已经了解了 MongoDB 如何概念化用户帐户,我们可以讨论如何创建新用户。请记住使用具有适当权限的用户登录到您的 MongoDB 服务器,以便继续操作。
要创建新用户,您必须首先切换到您要用作新用户的身份验证数据库的数据库。
首先,您可以通过键入以下内容来获取系统上已配置的数据库列表
show dbs
admin 0.000GBconfig 0.000GBlocal 0.000GB
使用 use
命令切换到用户将关联的数据库
use admin
switched to db admin
要创建新用户,您可以使用 db.createUser()
方法,也可以使用 createUser
数据库命令。无论哪种方式,您都需要在 user
对象中传递用户名(user
字段)、密码(pwd
字段)以及用户应添加到的角色数组(roles
键)。
要使用 db.createUser()
方法创建一个名为 tom
的新用户,密码设置为 hellothere
,角色数组为空,您可以键入
db.createUser({user: "tom",pwd: "hellothere",roles: []})
Successfully added user: { "user" : "tom", "roles" : [ ] }
使用 createUser
数据库命令的相同操作如下所示
db.runCommand({createUser: "tom",pwd: "hellothere",roles: []})
Successfully added user: { "user" : "tom", "roles" : [ ] }
这两种不同的选项非常相似,因此在接下来的内容中,我们将仅展示数据库方法(在适用情况下)。但是,如果您更喜欢数据库命令语法,您可以在 MongoDB 命令参考文档中找到每个关联的命令。
在上面的命令中,我们显式地在 user
对象中内联定义了密码。为了防止密码被记录和检索,您可以选择在 user
文档中使用 passwordPrompt()
方法,以便在运行命令时,MongoDB 以交互方式提示您输入密码。密码将不可见,因此您的命令历史记录将是干净的
db.createUser({user: "tom",pwd: passwordPrompt(),roles: []})
Enter password:Successfully added user: { "user" : "tom", "roles" : [ ] }
请记住,如果您未启用 TLS/SSL,密码仍将以明文形式发送到服务器。
如何显示现有用户?
接下来,让我们看看如何查找有关现有用户的信息。
要返回多个用户,您可以使用 db.getUsers()
方法来显示当前数据库中的所有用户。首先,切换到您感兴趣查询的数据库
use admin
接下来,使用 db.getUsers()
方法返回与当前数据库关联的所有用户
db.getUsers()
[{"_id" : "admin.root","userId" : UUID("f5ded238-19c9-4886-b649-711ec36993cb"),"user" : "root","db" : "admin","roles" : [{"role" : "root","db" : "admin"}],"mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"]},{"_id" : "admin.tom","userId" : UUID("e7a0abde-a9f9-412a-bfd5-eb11fda41fd3"),"user" : "tom","db" : "admin","roles" : [ ],"mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"]}]
要另外显示每个用户的凭据信息,请将一个对象传递给该方法,并将 showCredentials
键设置为 true
use admindb.getUsers({showCredentials: true})
[{"_id" : "admin.root",. . ."credentials" : {"SCRAM-SHA-1" : {"iterationCount" : 10000,"salt" : "WpB0H4f7dG8XlCDyaVzarA==","storedKey" : "b11nA1+mGo3+Tr8P//u3NEdJLHk=","serverKey" : "3xE8o663hjqySrMCQcXjSxmjmhk="},"SCRAM-SHA-256" : {"iterationCount" : 15000,"salt" : "UtsfNRedf2ek5tbWFoGs2g52U0H7Na44wV4rYA==","storedKey" : "mz9/qHnI79pNAIQm0MZTKZ0U3qFk0xhUDd2grvKtMdI=","serverKey" : "c/sA4j+I/29Ea1y07zxoMcBgHFoYTUAa6luX3Z9sToQ="}},. . .},{"_id" : "admin.tom",. . ."credentials" : {"SCRAM-SHA-1" : {"iterationCount" : 10000,"salt" : "qCbxWQSGt3QoN3S1aM5AEg==","storedKey" : "hypim5+m2wqbS1gc47o2itc7jew=","serverKey" : "h9myNoSvY2015yqvw3UldmJzZCg="},"SCRAM-SHA-256" : {"iterationCount" : 15000,"salt" : "lNtIVL79J8FF+uPaFfRMwPK079gfLEUrsQe3Qg==","storedKey" : "u8pgn3OJiZxIwEL7ryZkoAF5bnMefQEEsZDTXNDCTRY=","serverKey" : "BmmfVeikSA0DN1aZmyZP9NXi5owxGr1ZRmVX2XH8qVg="}},. . .}]
要查询与特定条件匹配的用户,您可以传递一个定义 filter
键的对象,该键定义匹配条件。
例如,要获取当前数据库中所有具有 root
角色的用户的信息,您可以键入
use admindb.getUsers({filter: {"roles.role": "root"}})
[{"_id" : "admin.root","userId" : UUID("f5ded238-19c9-4886-b649-711ec36993cb"),"user" : "root","db" : "admin","roles" : [{"role" : "root","db" : "admin"}],"mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"]}]
要获取特定用户,您可以改用 db.getUser()
方法。这与 db.getUsers()
方法类似,但返回单个用户。您无需将对象传递给该方法,而是传递一个包含您要检索的用户名的字符串
use admindb.getUser("tom")
{"_id" : "admin.tom","userId" : UUID("e7a0abde-a9f9-412a-bfd5-eb11fda41fd3"),"user" : "tom","db" : "admin","roles" : [ ],"mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"]}
您可以选择包含额外的 args
对象,该对象允许您通过将以下键设置为 true
来指定您想要的其他信息
showCredentials
:除了常规输出外,还显示凭据信息showPrivileges
:除了常规输出外,还显示权限信息showAuthenticationRestrictions
:除了常规输出外,还显示帐户上的身份验证限制
例如,您可以通过键入以下内容来告诉 MongoDB 为您提供上述所有信息
use admindb.getUser("tom",{showCredentials: true,showPrivileges: true,showAuthenticationRestrictions: true})
{"_id" : "admin.tom","userId" : UUID("e7a0abde-a9f9-412a-bfd5-eb11fda41fd3"),"user" : "tom","db" : "admin","mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"],"credentials" : {"SCRAM-SHA-1" : {"iterationCount" : 10000,"salt" : "qCbxWQSGt3QoN3S1aM5AEg==","storedKey" : "hypim5+m2wqbS1gc47o2itc7jew=","serverKey" : "h9myNoSvY2015yqvw3UldmJzZCg="},"SCRAM-SHA-256" : {"iterationCount" : 15000,"salt" : "lNtIVL79J8FF+uPaFfRMwPK079gfLEUrsQe3Qg==","storedKey" : "u8pgn3OJiZxIwEL7ryZkoAF5bnMefQEEsZDTXNDCTRY=","serverKey" : "BmmfVeikSA0DN1aZmyZP9NXi5owxGr1ZRmVX2XH8qVg="}},"roles" : [ ],"inheritedRoles" : [ ],"inheritedPrivileges" : [ ],"inheritedAuthenticationRestrictions" : [ ],"authenticationRestrictions" : [ ]}
如何更改 MongoDB 用户的密码?
要更改用户的密码,您可以使用 db.changeUserPassword()
方法。同样,您必须先切换到用户的身份验证数据库,然后再执行命令。
db.changeUserPassword()
方法接受两个参数:您要更改的帐户的用户名和该帐户的新密码。
例如,要将使用 admin
数据库进行身份验证的用户 tom
的密码更改为 secretpassword
,您可以键入
use admindb.changeUserPassword("tom", "secretpassword")
与 db.createUser()
方法一样,您可以将 passwordPrompt()
方法用于第二个参数,而不是内联提供密码。MongoDB 将提示您在执行命令时输入密码
use admindb.changeUserPassword("tom", passwordPrompt())
Enter password:
如何更改其他用户帐户详细信息?
要更改与用户帐户关联的其他信息,您可以使用 db.updateUser()
方法。在更新用户的详细信息之前,请确保切换到用户的身份验证数据库。
db.updateUser()
方法要求您指定用户名,然后提供一个包含您要更新的数据的对象。您选择更新的任何字段都将完全替换为新信息,因此如果您只想追加新信息,请务必在对象中包含原始数据以及新数据。
您在命令中包含的包含更改信息的对象可以包含许多不同的字段。让我们回顾一下它们
customData
:与用户帐户关联的任何任意数据。roles
:授予用户的角色。通常最好使用db.grantRolesToUser()
和db.revokeRolesFromUser()
方法来控制角色成员身份,而不是使用此键进行更新,因为您可以单独追加和删除角色。pwd
:用户的密码。如果只需要更新密码字段,则通常使用db.ChangeUserPassword()
方法会更容易。authenticationRestrictions
:指定帐户的限制,这些限制可以限制用户可以连接的 IP 地址或目标 IP 地址。此键的值是一个对象或数组,其中定义了clientSource
和/或serverAddress
,其中包含指定有效 IP 地址或范围的数组。有关更多信息,请参阅 MongoDB 文档中的身份验证限制。mechanisms
:用于凭据的特定身份验证机制。可以设置为SCRAM-SHA-1
或SCRAM-SHA-256
中的一个或两个,但如果当前未提供新密码,则只能更改为当前机制的子集。passwordDigestor
:指定哪个组件处理用户的密码。可以是server
(默认值)或client
。
例如,我们可以更新针对 admin
数据库进行身份验证的 tom
帐户,使其只能从托管服务器本身的同一台计算机登录,方法是更改 authenticationRestrictions
字段
use admindb.updateUser("tom", {authenticationRestrictions: [ {clientSource: ["127.0.0.1", "::1"],serverAddress: ["127.0.0.1", "::1"]} ]})
现在,如果您要求 MongoDB 向您显示有关用户的相关信息,它将显示帐户的其他限制
use admindb.getUser("tom", {showAuthenticationRestrictions: true})
{"_id" : "admin.tom","userId" : UUID("e7a0abde-a9f9-412a-bfd5-eb11fda41fd3"),"user" : "tom","db" : "admin","mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"],"roles" : [ ],"authenticationRestrictions" : [{"clientSource" : ["127.0.0.1","::1"],"serverAddress" : ["127.0.0.1","::1"]}],"inheritedRoles" : [ ],"inheritedPrivileges" : [ ],"inheritedAuthenticationRestrictions" : [ ]}
要撤销这些限制,我们可以使用空数组再次运行该命令
use admindb.changeUser("tom", {authenticationRestrictions: []})
如何删除 MongoDB 用户?
要删除 MongoDB 用户帐户,您可以使用 db.dropUser()
方法。在删除用户之前,请务必连接到用户的身份验证数据库。
要执行 db.dropUser()
方法,您需要提供您要删除的用户的名称
db.dropUser("tom")
成功删除后,MongoDB 将返回 true
true
如果该帐户在当前数据库中不存在,则它将返回 false
。
结论
MongoDB 的用户管理和身份验证配置使您可以控制谁可以连接到您的服务器以及他们的用户属性是什么。在后续文章中,我们将介绍如何通过处理用户管理的授权部分来限制用户拥有的访问级别。
如果您正在使用 MongoDB,请查看 Prisma 的 MongoDB 连接器!您可以使用 Prisma Client 自信地管理生产 MongoDB 数据库。
要开始使用 MongoDB 和 Prisma,请查看我们的 从零开始入门指南,或如何添加到现有项目。
常见问题解答
要在 MongoDB 中列出现有用户,您可以使用 db.getUsers()
方法来显示当前数据库中的所有用户。
语法如下所示
use admindb.getUsers()
有关 db.getUsers()
的更多详细信息。
为了在 MongoDB 中创建数据库管理员用户,您需要使用 admin
数据库中的 db.createUser()
方法。
以下演示了用于创建数据库管理员的语法。
use admindb.createUser({ user: "tom",pwd: "hellothere",roles:[{role: "dbAdmin" , db:"admin"}]})
要删除 MongoDB 用户,您可以使用 db.dropUser()
方法。这需要在 admin
数据库中完成,语法如下所示
use admindb.dropUser("tom")
要获取 MongoDB 中所有现有用户的列表,您可以使用 db.getUsers()
方法。
基本语法如下所示
use admindb.getUsers()
要查询特定用户,您可以使用 db.getUser()
方法,并将 showPrivileges
arg
设置为 true
。
基本语法如下所示
use admindb.getUser("tom",{showPrivileges: true,})