You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PyMongo连接MongoDB时认证失败问题求助

MongoDB认证失败:PyMongo连接失败但mongo shell成功

问题描述

使用Python的PyMongo连接MongoDB时触发认证失败错误,但通过mongo shell命令可正常连接并获取结果,相关代码及错误信息如下:

正常工作的mongo shell命令

mongo -u MYUSER -p MYPASSWD 127.0.0.1:27017/MYDB --authenticationDatabase admin --eval "printjson(db.getCollectionNames())"

报错的Python代码

import pymongo
import urllib.parse

host = "127.0.0.1"
port = 27017
user = "MYUSER"
password = "MYPASSWD"
dbname = "MYDB"

client = pymongo.MongoClient(f'mongodb://"{user}:{urllib.parse.quote_plus(password)}@{host}:{port}/{dbname}?authSource=admin')
#db = client.get_database()
db = client[dbname]
collection_vhs = db['vhs']

result = collection_vhs.find({"idSimple":"/01/"})
for doc in result:
        print(result)

报错信息

(env) root@MYHOST:~# python3 /etc/zabbix/scripts/mongodb_field_idSimple.py

Traceback (most recent call last):
  File "/etc/zabbix/scripts/mongodb_field_idSimple.py", line 21, in <module>
    for doc in result:
  File "/root/env/lib64/python3.6/site-packages/pymongo/cursor.py", line 1248, in next
    if len(self.__data) or self._refresh():
  File "/root/env/lib64/python3.6/site-packages/pymongo/cursor.py", line 1165, in _refresh
    self.__send_message(q)
  File "/root/env/lib64/python3.6/site-packages/pymongo/cursor.py", line 1053, in __send_message
    operation, self._unpack_response, address=self.__address
  File "/root/env/lib64/python3.6/site-packages/pymongo/mongo_client.py", line 1272, in _run_operation
    retryable=isinstance(operation, message._Query),
  File "/root/env/lib64/python3.6/site-packages/pymongo/mongo_client.py", line 1365, in _retryable_read
    with self._socket_from_server(read_pref, server, session) as (sock_info, read_pref):
  File "/usr/lib64/python3.6/contextlib.py", line 81, in __enter__
    return next(self.gen)
  File "/root/env/lib64/python3.6/site-packages/pymongo/mongo_client.py", line 1221, in _socket_from_server
    with self._get_socket(server, session) as sock_info:
  File "/usr/lib64/python3.6/contextlib.py", line 81, in __enter__
    return next(self.gen)
  File "/root/env/lib64/python3.6/site-packages/pymongo/mongo_client.py", line 1156, in _get_socket
    with server.get_socket(handler=err_handler) as sock_info:
  File "/usr/lib64/python3.6/contextlib.py", line 81, in __enter__
    return next(self.gen)
  File "/root/env/lib64/python3.6/site-packages/pymongo/pool.py", line 1379, in get_socket
    sock_info = self._get_socket()
  File "/root/env/lib64/python3.6/site-packages/pymongo/pool.py", line 1489, in _get_socket
    sock_info = self.connect()
  File "/root/env/lib64/python3.6/site-packages/pymongo/pool.py", line 1350, in connect
    sock_info.authenticate()
  File "/root/env/lib64/python3.6/site-packages/pymongo/pool.py", line 845, in authenticate
    auth.authenticate(creds, self)
  File "/root/env/lib64/python3.6/site-packages/pymongo/auth.py", line 549, in authenticate
    auth_func(credentials, sock_info)
  File "/root/env/lib64/python3.6/site-packages/pymongo/auth.py", line 475, in _authenticate_default
    return _authenticate_scram(credentials, sock_info, "SCRAM-SHA-1")
  File "/root/env/lib64/python3.6/site-packages/pymongo/auth.py", line 201, in _authenticate_scram
    res = sock_info.command(source, cmd)
  File "/root/env/lib64/python3.6/site-packages/pymongo/pool.py", line 764, in command
    exhaust_allowed=exhaust_allowed,
  File "/root/env/lib64/python3.6/site-packages/pymongo/network.py", line 164, in command
    parse_write_concern_error=parse_write_concern_error,
  File "/root/env/lib64/python3.6/site-packages/pymongo/helpers.py", line 180, in _check_command_response
    raise OperationFailure(errmsg, code, response, max_wire_version)
pymongo.errors.OperationFailure: Authentication failed., full error: {'ok': 0.0, 'errmsg': 'Authentication failed.', 'code': 18, 'codeName': 'AuthenticationFailed'}

问题原因

连接字符串中多了多余的双引号,导致用户名被错误地包含前引号(实际传递的用户名为"MYUSER),与真实用户名MYUSER不符,触发认证失败。

错误的连接字符串构造:

f'mongodb://"{user}:{urllib.parse.quote_plus(password)}@{host}:{port}/{dbname}?authSource=admin'

{user}前的"完全冗余且未闭合,是核心问题。

修正方案

移除连接字符串中的多余双引号,同时推荐使用参数式构造方式(可读性更强,避免字符串拼接错误),另外代码中print(result)需改为print(doc),否则打印的是游标对象而非文档内容。

修正后的代码

import pymongo
import urllib.parse

host = "127.0.0.1"
port = 27017
user = "MYUSER"
password = "MYPASSWD"
dbname = "MYDB"

# 方式1:修复后的字符串拼接
client = pymongo.MongoClient(f'mongodb://{user}:{urllib.parse.quote_plus(password)}@{host}:{port}/{dbname}?authSource=admin')

# 方式2:更推荐的参数式构造(可读性更强,不易出错)
# client = pymongo.MongoClient(
#     host=host,
#     port=port,
#     username=user,
#     password=password,
#     authSource='admin',
#     authMechanism='SCRAM-SHA-1'  # 可选,根据MongoDB认证机制调整
# )

db = client[dbname]
collection_vhs = db['vhs']

result = collection_vhs.find({"idSimple":"/01/"})
for doc in result:
        print(doc)  # 改为打印单个文档对象

内容的提问来源于stack exchange,提问作者sivsoft

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 09:47:10