web-dev-qa-db-fra.com

Comment échapper @ dans un mot de passe en connexion pymongo?

Ma question est une spécification de comment puis-je valider le mot de passe du nom d'utilisateur pour l'authentification mongodb via pymongo? .

J'essaie de me connecter à une instance MongoDB en utilisant PyMongo 3.2.2 et une URL qui contient l'utilisateur et le mot de passe, comme expliqué dans MongoDB Docs . La différence est que le mot de passe que j'utilise contient un '@'.

Au début, j'ai simplement essayé de me connecter sans m'échapper, comme ceci:

prefix = 'mongodb: //'

user = 'user: passw_with _ @ _'

suffixe = '@ 127.0.0.1: 27001 /'

conn = pymongo.MongoClient (préfixe + utilisateur + suffixe)

Naturellement, j'ai eu l'erreur suivante:

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

J'ai donc essayé d'échapper à l'utilisateur: passer une partie en utilisant rllib.quote () comme ceci:

prefix = 'mongodb: //'

user = urllib.quote ('utilisateur: passw_with _ @ _')

suffixe = '@ 127.0.0.1: 27001 /'

conn = pymongo.MongoClient (préfixe + utilisateur + suffixe)

mais j'ai eu un:

OperationFailure: Authentication failed.

(Il est important de dire qu'en utilisant un outil de gestion GUI MongoDB ( Robomongo , si cela importe), je peux me connecter à MongoDB en utilisant l'adresse (réelle) et les informations d'identification.)

L'impression d'une variable utilisateur dans le code ci-dessus a généré un 'user:passw_with_%40_' String (c'est-à-dire '@' est devenu '% 40') et selon wikipedia c'est l'échappement attendu.

J'ai même essayé d'échapper au @ avec des barres obliques inverses simples et doubles (user = 'user:passw_with_\\@_' et user = 'user:passw_with_\@_'), mais ceux-ci ont échoué avec l'exception InvalidURI.

TL; DR;

Ma question est la suivante: comment échapper à un '@' dans la partie mot de passe d'une URL MongoDB?

18
gmauch

Vous devriez pouvoir échapper le mot de passe en utilisant urllib.quote(). Bien que vous ne deviez citer/échapper que le mot de passe et exclure le username:; sinon le : sera également échappé dans %3A.

Par exemple:

import pymongo 
import urllib 

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

L'extrait ci-dessus a été testé pour MongoDB v3.2.x, Python v2.7 et PyMongo v3.2.2.

L'exemple ci-dessus supposé dans le chaîne de connexion MongoDB URI :

  • L'utilisateur est créé dans la base de données admin.
  • L'hôte mongod en cours d'exécution est 127.0.0.1 (localhost)
  • Le port mongod affecté à est 27001

Pour Python 3.x, vous pouvez utiliser rllib.parse.quote () pour remplacer les caractères spéciaux de votre mot de passe en utilisant le %xx échapper. Par exemple:

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

Python 3.6.5 - Version PyMongo 3.7.0 pour la connexion à une instance mlab :

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))

C'est la seule façon dont j'ai réussi à me connecter à l'instance mlab MongoDB sans utiliser l'application filée flask-pymongo, j'avais besoin de créer des appareils pour les tests unitaires.

Python 3.6.5 - version locale de 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]:27001/' % (username, password))
4
Conor