web-dev-qa-db-ja.com

pymongo接続でパスワードの@をエスケープする方法は?

私の質問は pymongoを介してmongodb認証のユーザー名パスワードを検証するにはどうすればよいですか? の仕様です。

MongoDB Docs で説明されているように、PyMongo 3.2.2と、ユーザーとパスワードを含むURLを使用してMongoDBインスタンスに接続しようとしています。違いは、使用しているパスワードに「@」が含まれていることです。

最初は、次のように、エスケープせずに接続しようとしました。

プレフィックス= '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.

だから私はこのように rllib.quote() を使用してuser:pass部分をエスケープしてみました:

プレフィックス= '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 によると、これは予期されるエスケープです。

@を1つまたは2つのバックスラッシュ(user = 'user:passw_with_\\@_'およびuser = 'user:passw_with_\@_')、しかしそれらはInvalidURI例外で失敗しました。

TL; DR;

私の質問は、MongoDB URLのパスワード部分の「@」をエスケープするにはどうすればよいですか?

18
gmauch

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)

上記のスニペットは、MongoDB v3.2.x、Python v2.7、および PyMongo v3.2.2に対してテストされました。

MongoDB URI接続文字列 で想定されている上記の例:

  • ユーザーはadminデータベースに作成されます。
  • 実行中のホストmongodは127.0.0.1(localhost)です
  • 割り当てられているポートmongodは27001です

Python 3.xの場合、 rllib.parse.quote() を使用して、%xxエスケープを使用してパスワードの特殊文字を置き換えることができます。例: :

url.parse.quote("p@ssword")
29
Wan Bachtiar

Python 3.6.5- mlab インスタンスに接続するための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:%[email protected]:000000/recipe_app_testing' % (username, password))

これは、フラスコ-ピモンゴスピンアップアプリを使用せずにmlab MongoDBインスタンスに接続できる唯一の方法であり、単体テスト用のフィクスチャを作成する必要がありました。

Python 3.6.5-PyMongo 3.7.0 localhostバージョン:

from pymongo import MongoClient
import urllib.parse 

username = urllib.parse.quote_plus('username')
password = urllib.parse.quote_plus('password')
client = MongoClient('mongodb://%s:%[email protected]:27001/' % (username, password))
4
Conor