前两天公司要求使用mangoDB完成商品数据的导入和查询, 苦逼在一天弄好之后, 晚上被架构师告知
-- 架构师:"你那边做好密码授权登陆了吗?"
-- 我:"没有啊, 我在本地测试的, 不是连服务器的本地吗? 要用户名密码干啥?"
-- 架构师:"mongo又不是只给你项目用的, 大家都要用, 怎么能没有账号密码呢?"
-- 我:"哦!"
-- 架构师:"给你账号密码, 你去吧!"
然后, 我发现, 架构师给我的是admin库的root身份账号. 由于是第一次接触mangodb, 真心不太会, 然后又苦逼学习了一番, 在此留下我的学习笔记
mongo -version :
➜ ~ mongo -version
MongoDB shell version v3.4.2
如何新建账号, 分配角色, 以及如何关联数据库
- 如何启动mongo在之前的笔记中(mongodb的下载安装)
已经提到了, 下面说说如何以授权认证方式启动
在基本启动mongodb服务的命令上
mongod --dbpath [数据存放path] // 基本命令
mongod --dbpath [数据存放path] -auth //开启授权启动
那么开启授权启动后, 需要怎么登陆呢??
如果是本机的话:
mongo
mongo命令就能够直接登陆了, 但是:
先使用命令看看我当前使用的数据库名
>db
test
>
我当前使用的库是test库,
接下来我们做一次数据插入
> db.Hello.insert({name:'World'})
2017-03-07T00:25:03.163+0800 I ACCESS [conn1] Unauthorized: not authorized on test to execute command { insert: "Hello", documents: [ { _id: ObjectId('58bd8d5f7118aa18e6286ec8'), name: "World" } ], ordered: true }
WriteResult({
"writeError" : {
"code" : 13,
"errmsg" : "not authorized on test to execute command { insert: \"Hello\", documents: [ { _id: ObjectId('58bd8d5f7118aa18e6286ec8'), name: \"World\" } ], ordered: true }"
}
})
>
可以看到结果, 没有授权在test上库执行inset命令(not authorized on test to execute...), 这就是说, 我们没有权限操作
这里简单聊一下mongodb中所有角色 权限链接
这里只列举最基本, 不做详细说明, 因为我也是学习者, 具体链接已给出, 详情可直接点击链接
分类 | role(角色) | 简要说明 |
---|---|---|
数据库用户角色(DB User Roles) |
read readWrite
|
为某个数据库创建一个用户, 分配该数据库的读写权力 |
数据库管理员角色(DB Admin Roles) |
dbAdmin dbOwner userAdmin
|
拥有创建数据库, 和创建用户的权力 |
集群管理角色(Culster Administration Roles) |
clusterAdmin clusterManager clusterMonitor hostManager
|
管理员组, 针对整个系统进行管理 |
备份还原角色(Backup and Restoration Roles) |
backup restore
|
备份数据库, 还原数据库 |
所有数据库角色(All-Database Roles) |
readAnyDatabase readWriteAnyDatabase userAdminAnyDatabase dbAdminAnyDatabase
|
拥有对admin操作的权限 |
Superuser Roles(超级管理员) | root |
dbOwner userAdmin userAdminAnyDatabase 这几个角色角色提供了任何数据任何用户的任何权限的能力,拥有这个角色的用户可以在任何数据库上定义它们自己的权限 |
我现在手上有一个root角色, 我们先使用root角色来我们的数据库创建一个用户
- 首先, 我们需要切换到admin数据库, 为什么呢? 因为我们的root角色用户是创建在admin数据的, 必须要到admin数据库去完成授权
> use admin //切换到admin数据库
switched to db admin
> db.auth('admin'.'admin') // 使用db.auth('用户名','密码')进行授权
2017-03-07T23:47:06.603+0800 E QUERY [thread1] SyntaxError: missing name after . operator @(shell):1:16
> db.auth('admin','admin')
2017-03-07T23:47:25.142+0800 I ACCESS [conn1] Successfully authenticated as principal admin on admin
1 // 返回1 授权成功, 否则返回0, 并提示失败
- 完成授权之后, 我们要携带root身份, 切换到我们对应的数据库, 那么先看看我们有哪些数据库再切换
> show dbs //展示所有数据库
admin 0.000GB
local 0.000GB
testDB 0.000GB //这个是我新建的
> use testDB // 切换到数据库
switched to db testDB
>
- 切换数据库之后, 我们为testDB创建一个用户
>db.createUser({user:'test',pwd:'test',roles:[{role:'readWrite',db:'testDB'}]})
Successfully added user: {
"user" : "test",
"roles" : [
{
"role" : "readWrite",
"db" : "testDB"
}
]
}
>
- 然后我们再切换到admin库, 看一下我们创建的用户, 这里先说一下, 为什么要到这个切换到testDB上创建用户, 因为只有在这里创建的用户才是这个数据库的用户, 才能在这里完成授权, 但是创建用户的信息存放在admin库中
> use admin
switched to db admin
> db.system.users.find({user:'test'})
{ "_id" : "testDB.test", "user" : "test", "db" : "testDB", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "CW0nvUZjVvlEqQPVbUAKpw==", "storedKey" : "zAPux5oBIOCb3PSZdMPDmFl1WkE=", "serverKey" : "aRFnK5cD1FQAkQeTU8eYvaZ0lQE=" } }, "roles" : [ { "role" : "readWrite", "db" : "testDB" } ] }
>
可以看到_id
说明我们的用户test
是属于testDB
数据库的. 并且分配的数据库也是testDB
那我们来测试一下test用户的读写吧!
为了避免之前授权root用户的影响, 我们先退出客户端 ,再登陆授权
> use testDB
switched to db testDB
> db.auth('test','test') // 进行test用户授权
2017-03-08T00:03:40.572+0800 I ACCESS [conn3] Successfully authenticated as principal test on testDB
1 //授权成功 // 下面提示没有在admin执行命令的权限 (不理会, 因为我们本来就没有权限)
2017-03-08T00:03:40.573+0800 I ACCESS [conn3] Unauthorized: not authorized on admin to execute command { replSetGetStatus: 1.0, forShell: 1.0 }
> db.Hello.insert({name:'World'})
WriteResult({ "nInserted" : 1 }) // 可以看到我插入了一条数据
> db.Hello.find() // 并且将其查出来了.
{ "_id" : ObjectId("58beda12ff72a6c747135225"), "name" : "World" }
>```
那么简单创建角色并且分配数据库等方法就说完了.
总结一下:
* 1) 一定要切换到对应的数据库去创建用户, 否则在进行认证的时候, 会提示找不到用户
* 2) 一定要到对应的数据库上去认证用户, 否则会认证授权失败
* 3) 不是所有人都能操作admin数据库, 分配给用户权限的时候,一定要谨慎
* 下面说说修改用户角色, 其实角色弄清楚了, 创建用户清楚了, 剩下都是命令简单介绍. 因为都一样
更新用户信息
```shell
>db.updateUser([用户名],{用户对象, 与创建时一样}) //其实后面还有一个可选参数, 一般不写. 需要自行百度writeConcern
那么这里简要说一下, 创建用户时和更新用户时,需要属性user
pwd
roles
成功修改后没有任何提示. 如下:
> db.updateUser('test',{user:'test',pwd:'admin',roles:[{role:'read',db:'testDB'}]}) //修改密码 并且 //修改角色为只读
>
以上需要注意的就是, roles
数组里的对象数据role
db
两个都需要给出, 否则会出现错误
剩下就没什么好说的了
- 删除用户
> use testDB
switched to db testDB
> db.dropUser('test')
true
>
注意哦, 修改用户和删除用户等等, 都和创建用户一样,需要切换到数据库管理员的身份哦, 也就是需要先切换到admin
库, 完成认证, 才能进行后面的操作. 同样需要到对应数据库去操作用户. 因为用户是跟着库走的.