簡介
管理使用者和身份驗證是管理 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 位址。此鍵的值是一個物件或陣列,用於定義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,})