My question is a specification of how can i validate username password for mongodb authentication through pymongo?.
I'm trying to connect to a MongoDB instance using PyMongo 3.2.2 and a URL that contains the user and password, as explained in MongoDB Docs. The difference is that the password I'm using contains a '@'.
At first I simply tried to connect without escaping, like this:
prefix = 'mongodb://'
user = 'user:passw_with_@_'
suffix = '@127.0.0.1:27001/'
conn = pymongo.MongoClient(prefix + user + suffix)
Naturally I got the following error:
InvalidURI: ':' or '@' characters in a username or password must be escaped according to RFC 2396.
So I tried escaping the user:pass part using urllib.quote() like this:
prefix = 'mongodb://'
user = urllib.quote('user:passw_with_@_')
suffix = '@127.0.0.1:27001/'
conn = pymongo.MongoClient(prefix + user + suffix)
but then I got a:
OperationFailure: Authentication failed.
(Important to say that using a GUI MongoDB Management Tool (Robomongo, if that matters) I'm able to connect to the MongoDB using the (real) address and credentials.)
Printing user variable in the code above generated a 'user:passw_with_%40_'
String (that is '@' became '%40') and according to wikipedia that's the expected escaping.
I even tried escaping the @ with single and double backslashes (user = 'user:passw_with_\\@_'
and user = 'user:passw_with_\@_'
), but those failed with the InvalidURI exception.
TL;DR;
My question is: How do I escape a '@' in the password part of a MongoDB URL?
You should be able to escape the password using urllib.quote()
. Although you should only quote/escape the password, and exclude the username:
;
otherwise the :
will also be escaped into %3A
.
For example:
import pymongo
import urllib
mongo_uri = "mongodb://username:" + urllib.quote("p@ssword") + "@127.0.0.1:27001/"
client = pymongo.MongoClient(mongo_uri)
The above snippet was tested for MongoDB v3.2.x, Python v2.7, and PyMongo v3.2.2.
The example above assumed in the MongoDB URI connection string:
- The user is created in the
admin
database. - The host
mongod
running on is 127.0.0.1 (localhost) - The port
mongod
assigned to is 27001
For Python 3.x, you can utilise urllib.parse.quote() to replace special characters in your password using the %xx
escape. For example:
url.parse.quote("p@ssword")
Python 3.6.5 - PyMongo 3.7.0 version for connecting to an mlab instance:
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))
This is the only way I have managed to connect to the mlab MongoDB instance without using flask-pymongo spun up app, I needed to create fixtures for unit tests.
Python 3.6.5 - PyMongo 3.7.0 localhost version:
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))
来源:https://stackoverflow.com/questions/39237813/how-to-escape-in-a-password-in-pymongo-connection