Pymongo在Python3上的SSL握手问题

时间:2019-02-01 18:03:53

标签: python python-3.x azure ssl azure-cosmosdb-mongoapi

尝试连接到Azure CosmosDB mongo服务器会导致SSL握手错误。

我正在使用Python3Pymongo连接到我的Azure CosmosDB。如果我使用Python27运行代码,则连接工作正常,但在使用Python3时导致以下错误:

import pymongo
from pymongo import MongoClient
import json
import sys

def check_server_status(client, data):
   '''check the server status of the connected endpoint'''
   db = client.result_DB
   server_status = db.command('serverStatus')
   print('Database server status:')
   print(json.dumps(server_status, sort_keys=False, indent=2, separators=(',', ': ')))
   coll = db.file_result
   print (coll)
   coll.insert_one(data)

def main():
    uri = "mongodb://KEY123@backend.documents.azure.com:10255/?ssl=true&replicaSet=globaldb"
    client = pymongo.MongoClient(uri)
    emp_rec1 = {
        "name":"Mr.Geek",
        "eid":24,
        "location":"delhi"
        }
    check_server_status(client, emp_rec1)

if __name__ == "__main__":
    main()

Python3上运行此命令会导致以下错误:

  

pymongo.errors.ServerSelectionTimeoutError:SSL握手失败:   backendstore.documents.azure.com:10255:[SSL:   CERTIFICATE_VERIFY_FAILED]证书验证失败(_ssl.c:749)

当我用Python27运行相同的代码时,这是我成功的输出:

  

数据库服务器状态:{“ _t”:“ OKMongoResponse”,“ ok”:1}   集合(数据库(MongoClient(host = ['backend.documents.azure.com:10255'],   document_class = dict,tz_aware = False,connect = True,ssl = True,   复制集='globaldb'),u'result_DB'),u'file_result')

5 个答案:

答案 0 :(得分:2)

在Mac Mojave 10.14.6上,我使用了(PyMongo 3.10和python 3.7)来解决:

烧瓶pymongo pymongo.errors.ServerSelectionTimeoutError [SSL:CERTIFICATE_VERIFY_FAILED]

在终端中执行:

sudo /Applications/Python\ 3.7/Install\ Certificates.command

如果您使用其他python版本,请仅更改版本号(在我的情况下,我有Python 3.7)

答案 1 :(得分:1)

解决了此更改的问题:

client = pymongo.MongoClient(uri, ssl_cert_reqs=ssl.CERT_NONE)

答案 2 :(得分:0)

PyMongo官方文档TLS / SSL和PyMongo的Troubleshooting TLS Errors部分介绍了以下问题。

  TLS错误通常分为两类,证书验证失败或协议版本不匹配。如果出现类似以下错误消息,则表明OpenSSL无法验证服务器的证书:

     

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed

     

这经常发生是因为OpenSSL无法访问系统的根证书或证书已过期。 Linux用户应确保已从其Linux供应商安装了最新的根证书更新。从python.org may have to run a script included with python下载的使用Python 3.6.0或更高版本的macOS用户,以安装根证书:

     

open "/Applications/Python <YOUR PYTHON VERSION>/Install Certificates.command"

     

使用较旧PyPy和PyPy3便携式版本的用户可能必须set an environment variable告诉OpenSSL在哪里可以找到根证书。使用pypi的certifi module可以轻松完成此操作:

$ pypy -m pip install certifi
$ export SSL_CERT_FILE=$(pypy -c "import certifi; print(certifi.where())")

您可以尝试按照上述说明解决您的问题,这似乎适用于Linux和Mac用户。在Windows上,我无法在Python 3.73.6中重现您的问题。如果您有任何疑问,请随时告诉我。

答案 3 :(得分:0)

尝试从Digital Ocean连接mongodb时遇到相同的问题, 通过将此函数与MongoClient中的参数一起使用来解决:

      onClick: function (val) {
    for (i = 0; i <
        positions[this.selected].SHC.length; i++) {
        var tag =
            positions[this.selected].SHC[i];
        var tagEl =
            document.createElement('p');
        var that = this;
        console.log(this.selected) // RETURNS CORRECT VALUE
        tagEl.onclick = function () {
            console.log(that.selected) // RETURNS UNKNOWN
            for (j = 0; j < positions[that.selected].SHC.length; j++) {

                if (positions[that.selected].SHC[j] == this.innerHTML) {
                    positions[that.selected].SHC.splice(j, 1);
                }
            };

        }
        tagEl.textContent = tag;
        document.getElementById("uldshtags").appendChild(tagEl);
    }
}

答案 4 :(得分:0)

在 Windows 上你可以这样做

<块引用>

pip 安装证书

然后在代码中使用:

import certifi
ca = certifi.where()

client = pymongo.MongoClient(
f"mongodb+srv://username:password@cluster0.xxxxx.mongodb.net/xyzdb?retryWrites=true&w=majority", tlsCAFile=ca)