选择数据库后进行身份验证

2024-01-04

我的 MongoDB 服务器中有 3 个数据库。我正在使用 pymongo 用 Python3 编写一些脚本。

我想使用最新的版本和做法。一旦我打开客户端并选择数据库,pymongo.MongoClient.['mydatabase'].authenticate 的 API 就会被弃用。https://api.mongodb.com/python/current/api/pymongo/database.html https://api.mongodb.com/python/current/api/pymongo/database.html

在选择数据库之前(在拨打客户端时)进行身份验证似乎并没有向下流向数据库。不仅适用于 pymongo,而且当我使用 mongo shell 时也是如此。所以我有一种感觉,这就是问题所在。

脚本.py

import pymongo
from pymongo import MongoClient
u = getUser()         # function which prompts for username
p = getPassword()     # getpass.getpass('Password')
uri = formatUri(u, p) # formats 'mongodb://%s:%s@%s'.format(user, password, host)

client = MongoClient(uri)
db = client['mydb']
col = db.mycollection
for doc in col.find():
    print(doc)

我收到错误消息,指出我无权使用该数据库。我知道我的帐户在 shell 中工作,但我必须先拨打客户端,然后使用数据库,然后进行身份验证。

这是一个 mongo shell 示例:

$ mongo
MongoDB shell version: v3.4.10
Connecting to: mongodb://127.0.0.1:port
MongoDB server version: v3.4.10
> use mydb
switched to mydb
> db.auth("user", "pass")
1

知道如何在选择数据库后进行身份验证,或者在使用数据库后它会记住我拨打的上下文吗?


您似乎在这里缺少一些概念,所以我基本上会回答作为您应该做什么的“指南”。因此,“身份验证”实际上并不是您在连接“之后”所做的事情,而是当您实际尝试进行身份验证时,您需要“查找正确的位置”。

我们可以通过基本上遵循中概述的过程来开始此操作启用身份验证 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"到连接字符串。就是这样完成的。


这实际上是“正在进行中”,以便与所有驱动程序在连接方式、身份验证发生位置以及选择数据库的位置方面保持一致。但有一些基本规则:

  1. 如果没有提供其他数据库命名空间以及身份验证凭据的连接详细信息,则"admin"被认为是default.

  2. 如果连接字符串上提供了数据库名称空间,这将用于身份验证这是数据库命名空间对连接字符串的实际意图。

  3. 尽管其他驱动程序“目前”在连接字符串上的数据库命名空间的角色方面有所不同,但用法正在更改为与所有驱动程序一致,“使用”数据库命名空间实际上是 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 中提供的“会话”功能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

选择数据库后进行身份验证 的相关文章

随机推荐

  • NoAutomaticTrigger 类型作业的连续 Azure WebJob 停止时的通知

    All 我正在将现有辅助角色代码迁移到 Azure Web 作业 我正在尝试使用 WebJob SDK 1 0 以便与 Azure 网站完全集成 我的困难是 JobHost 不能很好地处理超出其通常的基于属性的调用选项 队列 Blob 等
  • C++ 中的静态鸭子类型

    C 对于模板参数给出的类型有某种鸭子类型 我们不知道什么类型DUCK1 and DUCK2会的 但只要他们可以quack 它将编译并运行 template
  • 使用 Process.Start 在 C# 中打开 Excel 文件

    我正在尝试使用单击按钮打开 Excel 文件 由于某种原因它不起作用 我已经尝试了几件事 有什么想法为什么他们不工作吗 方法1我试过了 这将打开文件管理器 但不会打开正确的文件 它肯定使用了正确的文件路径并且该文件确实存在 private
  • 创建新的 GitHub 帐户后无法从私人存储库克隆/获取

    我是一名使用 git 和 SourceTree 的自由开发人员 在过去的几个月里 我一直在为一个拥有私有 GitHub 存储库的特定客户工作 在那段时间里我一直在使用 SourceTree 将更改拉取和推送到 GitHub 我有另一个客户希
  • Bootstrap3 轮播 - 随机选择下一张幻灯片

    我有点难住了 我是 Javascript 新手 但当我用 Google 搜索时 通常会在网上找到很多很棒的帮助 这次我能想到的最好的帮助就在这里 但文档说发布一个新问题比偏离原来的帖子更好 所以 这是我的问题 我正在使用 Bootstrap
  • Wordpress 数据库输出 - 删除 SQL 注入转义

    我在使用 wbdb 时遇到问题 当我使用 wpdb gt insert 或 wpdb gt update 插入或更新数据时 SQL 注入保护实际上会将 插入数据库 并且在输出该信息时 它会附带 SQL 转义 即 我的价值已转义 我知道必须有
  • 是否有满足 C99 标准的 static_assert 替代品?

    我一直在尝试实现类似的方法static assert这是在 C 11 标准中定义的 主要问题是C 编译器如何编写传递给的文本消息static assert as a const char 我可以让编译器写一条消息 比如A is not PO
  • 如何使用 @Template() 引用多个树枝

    我计划更新在 Symfony 3 0 上运行的应用程序 我曾经使用 Template 但是更新时 我必须在 中指定twig文件的根目录 但是 您需要更改 format 中index csv twig 和index html twig 的读取
  • 如何在react-native中为webView请求设置自定义标头

    我希望能够在 ruby on Rails 服务器端检测到 http 请求来自我的应用程序中的 webView 组件 该应用程序正在使用react native 特别是 我想区分来自应用程序的请求和来自在 ios 设备上运行的移动 safar
  • 请求变量如何由encodeURIComponent 使用 ISO-8859-1 字符集而不是 utf-8 进行编码?

    我在使用 ISO 8859 1 字符集的网站上工作 请求应该由encodeURIComponent 部分编码 但该函数使用utf 8编码 请求变量如何由encodeURIComponent使用ISO 8859 1字符集而不是utf 8进行编
  • 比较日期以检查旧文件

    我想检查文件是否早于一定时间 例如 2 天 我设法以这种方式获取文件创建时间 gt gt gt import os path time gt gt gt fileCreation os path getctime filePath gt g
  • Spring Cloud AWS - 无效标头发布 SNS 通知

    我正在尝试使用org springframework cloud aws messaging core NotificationMessagingTemplate 来自 Spring Cloud AWS 将通知发布到 SNS 主题 每次发布
  • 易失性数组的替代方案

    从其他问题中 我了解到易失性数组的元素不是易失性的 只有引用本身是不稳定的 volatile int data Thread A data 4 457 Thread B System out println data 4 在这里 线程 B
  • Python 2.7:如何在 Windows 上将新行的分隔符限制为 '\n'?

    当我在 Windows 上运行的 python 2 7 脚本中写入文本文件时 新行分隔符是 r n 但我希望它是 n 我尝试过使用open http docs python org 2 library io html io open wit
  • iframe 用于嵌入 flash 内容时的 Webkit 字体渲染

    请参见http jsfiddle net CVwXV 2 http jsfiddle net CVwXV 2 如果您使用的是 Mac 当您在 Mac 上的 Chrome 或 Safari webkit 上查看此内容时 文本会跳至更浅的阴影
  • 根据outlook邮件更新excel表[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我的目标是每当我收到特定主题的邮件时
  • 如何使用另一个 python 脚本文件中的参数执行 python 脚本文件

    我的问题是我想使用另一个 python 文件中的参数执行一个 python 文件以获取返回的值 不知道我有没有解释清楚 example 从外壳我执行这个 getCameras py path to the scene 这会返回给我一个相机列
  • Celery 不注册任务

    你好 我刚刚开始将 Celery 与 Django 一起使用 我有一项需要定期执行的任务 在管理界面中 我可以在名为 任务 已注册 的下拉列表中看到我的任务 但是当 Celery Beat 尝试执行它时 会抛出 NotRegistered
  • 用 C# 编写“原始”HTTP 客户端

    我正在尝试用 C 编写一个 原始 HTTP 客户端 你可能会问为什么 我的目标是在 J2ME 中实现 HTTP 客户端 只能执行 GET 和有限的 POST 但首先我需要更好地理解 HTTP 协议 因此进行 C 尝试 我的第一次尝试失败了
  • 选择数据库后进行身份验证

    我的 MongoDB 服务器中有 3 个数据库 我正在使用 pymongo 用 Python3 编写一些脚本 我想使用最新的版本和做法 一旦我打开客户端并选择数据库 pymongo MongoClient mydatabase authen