pymongo 身份验证在 python 脚本中失败

问题描述 投票:0回答:6

我已经安装了 mongodb 并启用了身份验证。及其工作发现。我可以使用 robomongo 应用程序从远程笔记本连接它:

Host: SERVER_IP
PORT: 27017
DATEBASE: prod-db
USERNAME: user_name
PASS: user_password
Auth Mechanism: MONGODB-CR

我们可以使用以下命令从本地服务器 shell 进行连接:

$ mongo prod-db -u user_name -p user_password

一切正常,但是当我们使用 pymongo api 尝试时。身份验证失败。下面是Python代码:

from pymongo import MongoClient

client = MongoClient()
client.prod_db.authenticate('user_name', 'user_password', mechanism='MONGODB-CR')
db = client.prod_db
result = db.users.find()

for document in result:
    print(document)

使用工具:

python 2.7
pymongo versiob 3.3.1
MongoDB shell version: 2.6.10
$ mongod --version
db version v2.6.10
2016-10-31T16:34:59.868+0000 git version: nogitversion
2016-10-31T16:34:59.868+0000 OpenSSL version: OpenSSL 1.0.2g  1 Mar 2016

错误追踪:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pymongo/database.py", line 1018, in authenticate
    connect=True)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/mongo_client.py", line 444, in _cache_credentials
    sock_info.authenticate(credentials)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/pool.py", line 343, in authenticate
    auth.authenticate(credentials, self)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/auth.py", line 464, in authenticate
    auth_func(credentials, sock_info)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/auth.py", line 439, in _authenticate_mongo_cr
    sock_info.command(source, query)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/pool.py", line 239, in command
    read_concern)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/network.py", line 102, in command
    helpers._check_command_response(response_doc, None, allowable_errors)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/helpers.py", line 205, in _check_command_response
    raise OperationFailure(msg % errmsg, code, response)

解决方案: 问题出在数据库名称上,以下代码工作正常:

from pymongo import MongoClient

client = MongoClient('mongodb://user_name:user_password@localhost:27017/prod-db')
db = client['prod-db']

result = db.users.find()
for document in result:
    print document
python mongodb pymongo
6个回答
61
投票

请尝试这样的事情:

client = MongoClient("mongodb://user_name:user_password@SERVER_IP/prod-db")
db = client['prod-db']

32
投票

如果您已尝试上述答案(来自 milos.ai)但仍然收到错误:

pymongo.errors.OperationFailure: Authentication failed.

您很有可能需要将

?authSource=admin
添加到您的 uri 末尾。

这是我与 MongoDB 服务器版本 4.2.6 和 MongoDB shell 版本 v3.6.9 一起使用的有效解决方案。

from pymongo import MongoClient

# Replace these with your server details
MONGO_HOST = "XX.XXX.XXX.XXX" 
MONGO_PORT = "27017"
MONGO_DB = "database"
MONGO_USER = "admin"
MONGO_PASS = "pass"

uri = "mongodb://{}:{}@{}:{}/{}?authSource=admin".format(MONGO_USER, MONGO_PASS, MONGO_HOST, MONGO_PORT, MONGO_DB)
client = MongoClient(uri)

如果您使用命令行,您将通过添加参数来获得相同的修复

--authenticationDatabase admin


16
投票

对于 pymongo,

尝试以下

MongoDB 4

添加

authSource
:这是包含用户凭据集合的数据库的名称。

例如:

client = MongoClient(host=<<hostname>>,
                     port=<<port>>, 
                     username=<<user_name>>, 
                     password=<<password>>,
                    authSource="admin")
db_obj = client[db_name]

编辑1:我也在 Mongo 3.x 版本上尝试过这个。也为此而努力。


3
投票

这对我有用......

import pymongo

client = pymongo.MongoClient("mongodb://username:12%40password@ip:27017/sample_db",authSource="admin") 
db = client['sample_db']

请记住,如果您的密码中包含特殊字符(例如#、@),您将需要在密码中对它们进行编码(请参阅%40)。如果您不执行 authSource="admin" 您将收到身份验证错误。 username - 您的 mongodb 用户名,ip - IP 地址,因为这假设数据库托管在远程服务器上。 Sample_db 是您要访问的数据库。


0
投票

我解决了类似的问题,如下所示;

正如 pymongo 文档所述,您应该使用 urllib 作为用户名和密码。 https://pymongo.readthedocs.io/en/stable/examples/authentication.html

我的代码在这里;

import os, urllib

user = urllib.parse.quote_plus(os.environ.get('MONGO_USER'))
password = urllib.parse.quote_plus(os.environ.get('MONGO_PASS'))

uri = "mongodb://{}:{}@{}:{}".format(user, password, os.environ.get('MONGO_HOST'), os.environ.get('MONGO_PORT'))
## if you have an admin user you should not specify any database name in uri. After connection established you can call get_database('your_db_name')
client = MongoClient(uri)

注意:身份验证需要用户名、密码和数据库名称。默认数据库名称是“admin”,可以使用 authSource 选项覆盖它。因此,如果您有可以访问任何数据库的 root 用户,则不必指定 authSource。默认值已经是 .


0
投票

我使用的是 pymongo 版本 = 3.4.0 和 python 版本 = 3.6.2。 将 pymongo 降级到 3.11,它对我有用。

© www.soinside.com 2019 - 2024. All rights reserved.