25

私の質問は、pymongo を介して mongodb 認証のユーザー名パスワードを検証する方法の仕様です。.

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

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

プレフィックス = 'mongodb://'

ユーザー = 'ユーザー: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 部分をエスケープしようとしました。

プレフィックス = 'mongodb://'

ユーザー = 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」になりました)、ウィキペディアによると、これは予想されるエスケープです。

@ を単一および二重のバックスラッシュ (user = 'user:passw_with_\\@_'およびuser = 'user:passw_with_\@_') でエスケープしようとしましたが、それらは InvalidURI 例外で失敗しました。

TL;DR;

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

4

4 に答える 4

45

を使用してパスワードをエスケープできるはずです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 では、urllib.parse.quote()%xxを使用して、エスケープを使用してパスワードの特殊文字を置き換えることができます。例えば:

url.parse.quote("p@ssword")
于 2016-09-02T02:05:10.663 に答える