
0.前言
mongodb作為時下最為熱門的數(shù)據(jù)庫,那么其安全驗證也是必不可少的,否則一個沒有驗證的數(shù)據(jù)庫暴露出去,任何人可隨意操作,這將是非常危險的。
本篇就mongodb的用戶操作及用戶驗證來作探討。
1. 安裝
老生常談的話題,網(wǎng)上很多優(yōu)秀的教程,這里不再細(xì)說。
自docker面世以來,后端部署和環(huán)境搭建已逐漸步入容器化時代,作為一名有追求有作為的程序員,你有必要對前沿的技術(shù)有所了解和探討。
個人推薦使用docker搭建你的mongodb,操作也十分簡單。
首先,獲取docker官方的mongodb鏡像,也可以是第三方源的鏡像
docker pull mongo
效果圖如下:

其次,啟動你的mongo鏡像,如下:
docker run --name mymongo -p 27017:27017 -v /home/mongodb/data:/data/db -d mongo
簡單解釋下:
docker run 命令用于啟動一個容器, --name mymongo 指定容器的名稱為mymongo
-p 27017:27017,將容器內(nèi)27017端口映射到服務(wù)器27017端口
-v /home/mongodb/data:/data/db,指定數(shù)據(jù)存儲目錄/home/mongodb/data映射到容器內(nèi)的/data/db存儲目錄
-d 守護進(jìn)程運行
mongo 指定運行的鏡像
那么,如何開啟驗證呢?
也簡單,只需要加上--auth即可:
docker run --name mymongo -p 27017:27017 -v /home/mongodb/data:/data/db -d mongo --auth
至此,一個mongo容器就可以跑起來了,還有更多可操作的地方,不在主題范圍內(nèi),這里不做詳細(xì)闡述。
要注意的是,首次啟動,或還沒有設(shè)置用戶驗證之前,請不要開啟驗證,后面會講到。
2. 創(chuàng)建db管理賬戶
在創(chuàng)建用戶之前,我們來看看db用戶具體可以有哪些權(quán)限:
mongodb用戶權(quán)限列表:
Read:允許用戶讀取指定數(shù)據(jù)庫
readWrite:允許用戶讀寫指定數(shù)據(jù)庫
dbAdmin:允許用戶在指定數(shù)據(jù)庫中執(zhí)行管理函數(shù),如索引創(chuàng)建、刪除,查看統(tǒng)計或訪問system.profile
userAdmin:允許用戶向system.users集合寫入,可以找指定數(shù)據(jù)庫里創(chuàng)建、刪除和管理用戶
clusterAdmin:只在admin數(shù)據(jù)庫中可用,賦予用戶所有分片和復(fù)制集相關(guān)函數(shù)的管理權(quán)限。
readAnyDatabase:只在admin數(shù)據(jù)庫中可用,賦予用戶所有數(shù)據(jù)庫的讀權(quán)限
readWriteAnyDatabase:只在admin數(shù)據(jù)庫中可用,賦予用戶所有數(shù)據(jù)庫的讀寫權(quán)限
userAdminAnyDatabase:只在admin數(shù)據(jù)庫中可用,賦予用戶所有數(shù)據(jù)庫的userAdmin權(quán)限
dbAdminAnyDatabase:只在admin數(shù)據(jù)庫中可用,賦予用戶所有數(shù)據(jù)庫的dbAdmin權(quán)限。
root:只在admin數(shù)據(jù)庫中可用。超級賬號,超級權(quán)限
mongodb有一個用戶管理機制,簡單描述為,有一個管理用戶組,這個組的用戶是專門為管理普通用戶而設(shè)的,暫且稱之為管理員。
管理員通常沒有數(shù)據(jù)庫的讀寫權(quán)限,只有操作用戶的權(quán)限, 因此我們只需要賦予管理員userAdminAnyDatabase角色即可
另外管理員賬戶必須在admin數(shù)據(jù)庫下創(chuàng)建,3.0版本后沒有admin數(shù)據(jù)庫,但我們可以手動use一個
use admin
下面我們來創(chuàng)建一個管理賬戶
首先,要進(jìn)入mongo,以我本地數(shù)據(jù)庫為例
如圖:

如果數(shù)據(jù)庫使用docker搭建的,則需要進(jìn)入你的mongo容器內(nèi)去操作。
比如,以我的服務(wù)器mongo鏡像為例:

切換到admin數(shù)據(jù)庫,創(chuàng)建管理員
進(jìn)入mongo之后,那么意味著我們可以操作db了。
需要明白的一點是,管理員需要在admin數(shù)據(jù)庫下創(chuàng)建,所以我們得進(jìn)入admin數(shù)據(jù)庫
使用use命令,即可進(jìn)入某個數(shù)據(jù)庫,如下:
use admin
切換到admin數(shù)據(jù)庫后,我們可以查看db的用戶列表,此時用戶列表是空的,因為我們還沒有創(chuàng)建db用戶
db.system.users.find()
# 此時列表為空
接著,開始創(chuàng)建你的管理員賬戶,比如,創(chuàng)建一個用戶名為super, 密碼為superpwd的管理員賬戶:
db.createUser({
user: ‘super’,
pwd: ‘superpwd’,
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] });
成功則會提示Successfully
注意:這里使用createUser()方法來創(chuàng)建,addUser()方法已經(jīng)被廢棄
管理員授權(quán)
創(chuàng)建管理員后,需要給管理員授權(quán),否則無權(quán)限操作用戶
授權(quán)也十分簡單,如下:
db.auth('super','superpwd')
如果結(jié)果返回1,則表示授權(quán)成功,返回0則表示失敗
至此,管理員創(chuàng)建完成。
下面是完整流程:

3. 使用管理員賬戶創(chuàng)建普通用戶
普通用戶由管理員創(chuàng)建,并授權(quán)。通常需要指定某個數(shù)據(jù)庫來操作。
先看需求
比如,現(xiàn)在我需要創(chuàng)建一個blog數(shù)據(jù)庫,并且給這個數(shù)據(jù)庫添加一個用戶,用戶名為develop,密碼為developpwd,
只有這個用戶可以操作這個blog數(shù)據(jù)庫。
管理員賬戶登錄
需要明白一點的是,普通用戶需要由管理員創(chuàng)建并授權(quán),所以,我們首先做的就是用管理員賬戶登錄數(shù)據(jù)庫
提示:在管理員賬戶創(chuàng)建完成后,我們需要重新啟動數(shù)據(jù)庫,并開啟驗證
以docker為例:
# 重新啟動,開啟驗證
docker run --name mymongo -p 27017:27017 -v /home/mongodb/data:/data/db -d mongo --auth
重新啟動之后,我們就可以用管理員賬戶進(jìn)入mongo,如下:
# 指定用戶進(jìn)入mongo可使用: mongo admin -u 用戶名 -p 密碼
mongo admin -u super -p superpwd
進(jìn)入之后,我們就可以做用戶操作了
創(chuàng)建數(shù)據(jù)庫,并創(chuàng)建用戶
進(jìn)入mongo之后,首先切換到blog數(shù)據(jù)庫
use blog
# 沒有則會自動創(chuàng)建
緊接著,可以創(chuàng)建develop用戶了
db.createUser({
user: "develop",
pwd: "developpwd",
roles: [ { role: "readWrite", db: "blog" } ]
})
# 指定可訪問blog數(shù)據(jù)庫,并給予readWrite(讀寫)權(quán)限
再接著就是給develop用戶授權(quán)了
db.auth('develop','developpwd')
至此,普通用戶develop創(chuàng)建完成。
這時,我們就可以使用develop用戶連接blog數(shù)據(jù)庫了,如下;
mongo mongodb://develop:developpwd@localhost:27017/blog
至此,用戶驗證處理完成。
4. 一些用戶操作命令
提示: 需要使用管理員賬戶來操作
創(chuàng)建用戶
db.createUser({
user:用戶名,
pwd:密碼,
roles:[
{ role:權(quán)限類型, db:可訪問的db}
]
})
查看用戶列表
db.system.users.find()
查看某個用戶信息
db.runCommand({usersInfo:用戶名})
修改用戶信息
db.runCommand(
{
updateUser:用戶名,
pwd:密碼,
customData:{title:"xxx"……}
}
)
修改用戶密碼
db.changeUserPassword(‘user’,’pwd’);
刪除用戶
db.system.users.remove({user:”username”});
本文首發(fā)于我的個人站點:http://sinn.boyagirl.com/detail/58d9072cc1a5bd0001672cdc
以及我的github blog:https://github.com/sessionboy/blog