【问题标题】:How to escape @ in a password in pymongo connection?如何在pymongo连接中的密码中转义@?
【发布时间】:2022-04-24 07:22:06
【问题描述】:

我的问题是how can i validate username password for mongodb authentication through pymongo? 的规范。

我正在尝试使用 PyMongo 3.2.2 和包含用户和密码的 URL 连接到 MongoDB 实例,如 MongoDB Docs 中所述。不同之处在于我使用的密码包含一个“@”。

起初我只是尝试连接而不转义,如下所示:

prefix = 'mongodb://'

user = 'user:passw_with_@_'

后缀 = '@127.0.0.1:27001/'

conn = pymongo.MongoClient(前缀+用户+后缀)

我自然得到以下错误:

InvalidURI: ':' or '@' characters in a username or password must be escaped according to RFC 2396.

所以我尝试使用 urllib.quote() 转义 user:pass 部分,如下所示:

prefix = 'mongodb://'

user = urllib.quote('user:passw_with_@_')

后缀 = '@127.0.0.1:27001/'

conn = pymongo.MongoClient(前缀+用户+后缀)

但后来我得到了一个:

OperationFailure: Authentication failed.

(重要的是,使用 GUI MongoDB 管理工具(Robomongo,如果这很重要)我可以使用(真实)地址和凭据连接到 MongoDB。)

在上面的代码中打印用户变量生成了一个'user:passw_with_%40_' 字符串(即'@'变成了'%40'),根据wikipedia,这是预期的转义。

我什至尝试使用单反斜杠和双反斜杠(user = 'user:passw_with_\\@_'user = 'user:passw_with_\@_')转义 @,但由于 InvalidURI 异常而失败。

TL;DR;

我的问题是:如何在 MongoDB URL 的密码部分中转义“@”?

【问题讨论】:

    标签: python mongodb authentication pymongo-3.x


    【解决方案1】:

    您应该能够使用urllib.quote() 转义密码。虽然您应该只引用/转义密码,并排除 username: ; 否则: 也将转义为%3A

    例如:

    import pymongo 
    import urllib 
    
    mongo_uri = "mongodb://username:" + urllib.quote("p@ssword") + "@127.0.0.1:27001/"
    client = pymongo.MongoClient(mongo_uri)
    

    上述 sn-p 已针对 MongoDB v3.2.x、Python v2.7 和 PyMongo v3.2.2 进行了测试。

    上面的例子假设在MongoDB URI connection string:

    • 用户是在admin 数据库中创建的。
    • 运行的主机mongod是127.0.0.1 (localhost)
    • mongod分配的端口是27001

    对于 Python 3.x,您可以利用 urllib.parse.quote() 使用 %xx 转义符替换密码中的特殊字符。一个相同的例子:

    urllib.parse.quote("p@ssword")
    

    【讨论】:

    • Python 3:urllib.parse.quote
    • Conor 有一个待定的编辑。由于缺乏任何其他方式直接与编辑联系,我希望能阅读此评论。康纳,你的编辑添加了如此好的信息,它应该是它自己的答案。我拒绝了该编辑,因为它本身可以更好地为(您和)社区提供答案。
    【解决方案2】:

    Python 3.6.5 - PyMongo 3.7.0 版本,用于连接mlab 实例:

    from pymongo import MongoClient
    import urllib.parse
    
    username = urllib.parse.quote_plus('username')
    password = urllib.parse.quote_plus('password')
    client = MongoClient('mongodb://%s:%s@ds00000.mlab.com:000000/recipe_app_testing' % (username, password))
    

    这是我设法连接到 mlab MongoDB 实例而不使用 flask-pymongo 启动应用程序的唯一方法,我需要为单元测试创​​建夹具。

    Python 3.6.5 - PyMongo 3.7.0 本地主机版本:

    from pymongo import MongoClient
    import urllib.parse 
    
    username = urllib.parse.quote_plus('username')
    password = urllib.parse.quote_plus('password')
    client = MongoClient('mongodb://%s:%s@127.0.0.1:27001/' % (username, password))
    

    【讨论】:

      【解决方案3】:

      在终端运行:

      python -m pip install pymongo[srv]
      

      python 文件:

      import pymongo
      from pymongo import MongoClient
      import urllib.parse
      
      username = urllib.parse.quote_plus('username')
      password = urllib.parse.quote_plus("password")
      
      url = "mongodb+srv://{}:{}@cluster0-0000.mongodb.net/<dbname>?retryWrites=true&w=majority".format(username, password)
      # url is just an example (your url will be different)
      
      cluster = MongoClient(url)
      db = cluster['Sample']
      collection = db['temporary']
      

      【讨论】:

        【解决方案4】:

        只是信息:

        MongoDB、pymongo 和 mongoengine 无法处理密码中的多个符号;

        Windows 数据库名称限制

        /\. "$*<>:|?
        

        Unix 和 Linux 系统的数据库名称限制

        /\. "$
        

        https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names

        包含非法符号时转义不起作用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-06-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-18
          • 2022-12-15
          相关资源
          最近更新 更多