您似乎在这里缺少一些概念,所以我基本上会回答作为您应该做什么的“指南”。因此,“身份验证”实际上并不是您在连接“之后”所做的事情,而是当您实际尝试进行身份验证时,您需要“查找正确的位置”。
我们可以通过基本上遵循中概述的过程来开始此操作启用身份验证 https://docs.mongodb.com/manual/tutorial/enable-authentication/来自核心文档,但经过专门更改,因为您希望在自己的用户帐户和本地目录下运行此“测试”。
修订步骤 - 直接来自文档
因此,首先需要选择一个本地工作目录,并为该目录下的数据库存储文件创建一个路径。在基于 *nix 的系统上,您可以执行以下操作:
mkdir -p scratch/data/db
cd scratch
然后我们想要启动一个单独的 MongoDB 实例,而无需任何其他选项。确保端口不与任何其他正在运行的实例冲突:
mongod --port 37017 --dbpath data/db
在新的终端或命令行窗口中,您可以连接到 shell:
mongo --port 37017
您总是希望至少有一个具有管理权限的帐户来至少“创建帐户”并更改它们,以防遇到麻烦,因此创建一个:
use admin
db.createUser(
{
user: "admin",
pwd: "admin",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
}
)
现在退出 shell 并关闭现有的mongod
在另一个终端或命令提示符中运行的实例,然后使用再次启动它--auth
:
mongod --auth --port 37017 --dbpath data/db
特定用户 - 确保您遵循这些
现在您实际上想要创建一个将“由您的应用程序使用”的用户。因此,这些步骤对于确保您正确执行非常重要。
使用您的“管理用户”登录 shell:
mongo -u admin -p admin --port 37017 --authenticationDatabase 'admin'
您可以交替执行db.auth()
问题中所示的方法,但正如所指出的must被授权于"admin"
命名空间。
您要做的下一件事是创建一个有权访问的用户"mydb"
作为命名空间readWrite
角色。为了好玩,我们还将让该用户拥有readAnyDatabase
允许他们“列出”所有数据库名称空间,即使实际上无法对它们执行任何其他操作。
重要的:您在中创建所有用户"admin"
命名空间。这在未来的版本中将非常重要:
use admin
db.createUser(
{
"user": "myuser",
"pwd": "password",
"roles": [
{ "role": "readWrite", "db": "mydb" },
"readAnyDatabase"
]
}
)
为了获得额外的输出,让我们看看当前创建的用户:
db.getUsers()
[
{
"_id" : "admin.admin",
"user" : "admin",
"db" : "admin",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
},
{
"_id" : "admin.myuser",
"user" : "myuser",
"db" : "admin",
"roles" : [
{
"role" : "readWrite",
"db" : "mydb"
},
{
"role" : "readAnyDatabase",
"db" : "admin"
}
]
}
]
了解它们在命名方面的扩展,特别是分配给各个变量的值"db"
每个用户的密钥。这应该能让您更深入地了解 MongoDB 如何查找此问题以及原因。
Python连接
最后我们只想从 python 连接。因此,假设您已经安装了 python 和 pymongo,那么这只是一个需要验证的简单列表:
import pymongo
from pymongo import MongoClient
client = MongoClient('mongodb://myuser:password@localhost:37017');
db = client['mydb']
col = db.test
col.remove()
col.insert_one({ "a": 1 })
for doc in col.find():
print(doc)
这显示了创建并列出的文档没有问题:
{u'a': 1, u'_id': ObjectId('5a08e5e0760108251722a737')}
请注意,我们实际上不需要提及"admin"
在这里,因为这是驱动程序“期望帐户所在”的默认位置,也是您真正“应该”执行此操作的位置。
但我做错了
假设您最初感到困惑并在下面创建了用户"mydb"
反而:
use mydb
db.createUser({ "user": "bert", "pwd": "password", "roles": ["readWrite"] })
如果你进去看看"admin"
该用户不存在。但如果你看着"mydb"
:
use mydb
db.getUsers()
[
{
"_id" : "mydb.bert",
"user" : "bert",
"db" : "mydb",
"roles" : [
{
"role" : "readWrite",
"db" : "mydb"
}
]
}
]
因此,您可以看到实际用户数据现在保存在哪里以及如何记录。
这里的简单情况是您“必须”告诉 MongoDB 从哪里获取该用户的身份验证:
client = MongoClient('mongodb://bert:password@localhost:37017/mydb');
看看我们如何添加"mydb"
到连接字符串。就是这样完成的。
这实际上是“正在进行中”,以便与所有驱动程序在连接方式、身份验证发生位置以及选择数据库的位置方面保持一致。但有一些基本规则:
-
如果没有提供其他数据库命名空间以及身份验证凭据的连接详细信息,则"admin"
被认为是default.
-
如果连接字符串上提供了数据库名称空间,这将用于身份验证这是数据库命名空间对连接字符串的实际意图。
-
尽管其他驱动程序“目前”在连接字符串上的数据库命名空间的角色方面有所不同,但用法正在更改为与所有驱动程序一致,“使用”数据库命名空间实际上是 API 调用,而不是从连接字符串。
因此,您需要在哪里进行身份验证取决于“您创建用户的位置”。但你真的应该注意到"admin"
是您“应该”执行此操作的地方,而不是其他任何地方。
弃用连接后进行身份验证
虽然所有驱动程序实际上都有类似的方法authenticate() https://api.mongodb.com/python/current/api/pymongo/database.html#pymongo.database.Database.authenticate,其使用方式与问题中的 shell 示例非常相似,现在考虑这种方法已弃用正如整个答案的内容所提到的,您“打算”将您的用户实际存储在"admin"
命名空间:
“在版本 3.5 中进行了更改:已弃用。对多个用户进行身份验证与 MongoDB 3.6 中对逻辑会话的支持相冲突。要以多个用户身份进行身份验证,请创建 MongoClient 的多个实例。”
这就是为什么这里的整个答案基于NOT使用该方法,因为您打算创建新的连接实例,或者使用 MongoDB 3.6 中提供的“会话”功能。