折腾:
期间,去试试
结果:
mongodbUri = "mongodb://%s:%s@%s" % (quote_plus("gridfs"), quote_plus("pwd"), quote_plus("xxx:27017"))
会报错:
Authentication failed
而换成:
mongodbUri = "mongodb://%s:%s@%s" % (quote_plus("gridfs"), quote_plus("pwd"), quote_plus("xxx:27017/gridfs"))
会报错:
ValueError: Port must be an integer between 0 and 65535: 27017/gridfs
经过尝试发现:
代码中,用MongoClient主动加上参数authSource指定要验证的数据库:
(类似于参数–authenticationDatabase)
mongoClient = MongoClient( host="xxx", port=27017, username="gridfs", password="pwd", authSource="gridfs" ) logging.info("mongoClient=%s", mongoClient) gridfsDb = mongoClient.gridfs logging.info("gridfsDb=%s", gridfsDb) fsCollection = GridFS(gridfsDb) logging.info("fsCollection=%s", fsCollection)
后才能有对应的读写权限:
而之前的:
mongodbUri = "mongodb://%s:%s@%s" % (quote_plus("gridfs"), quote_plus("pwd"), quote_plus("xxx:27017/gridfs")) # ' mongodb://gridfs:N%40tur1ing@xxx%3A27017%2Fgridfs ’ mongoClient = MongoClient(mongodbUri)
虽然uri的写法,符合:
“* authSource: The database to authenticate on. Defaults to the database specified in the URI, if provided, or to “admin”.”
中说的,把要验证的数据库放在了uri
中了,但是却会报错:
ValueError: Port must be an integer between 0 and 65535: 27017/gridfs
好像是bug??
不过,反正是通过加了参数,是可以正常有权限操作的。
但是,还是再去试试,把:
ongodbUri = "mongodb://%s:%s@%s" % (quote_plus("gridfs"), quote_plus("pwd"), quote_plus("xxx:27017/gridfs"))
改造一下:
mongodbUri = "mongodb://%s:%s@%s:%s/%s" % ( quote_plus("gridfs"), \ quote_plus("pwd"), \ "xxx", \ 27017, \ "gridfs" \ ) mongoClient = MongoClient(mongodbUri)
然后发现也是可以正常有权限操作的:
-》证明之前的uri的写法,把端口号:数据库名字,即:
27017/gridfs
一起quote_plus,导致人家MongoClient内部解析端口发现端口叫做:
27017/gridfs
而不是
27017
所以报错的
-》属于自己使用不当
-〉MongoClient是可以正常的,在uri中指定要验证的数据库的
-》验证成功后,即可读写等操作。
【总结】
在远程MongoDB添加了访问权限控制后,
此处Python的driver:PyMongo中,可以通过uri,也可以通过参数,去验证用户,去登录并操作数据库的。
方法1: 在uri中指定用户名,密码,要验证的数据库
mongodbUri = "mongodb://%s:%s@%s:%s/%s" % ( quote_plus("gridfs"), \ quote_plus("pwd"), \ "xxx", \ 27017, \ "gridfs" \ ) #'mongodb://gridfs:N%40tur1ing@xxx:27017/gridfs ’ mongoClient = MongoClient(mongodbUri)
-》优化后为:
MongoHostRemote = "xxx" MongoHostLocal = "localhost" # MongoHostLocal = "127.0.0.1" # MongoHost = MongoHostRemote MongoHost = MongoHostLocal MongoPort = 27017 # MongoUseAuth = True MongoUseAuth = False # with auth MongoUsername = "gridfs" MongoPassword = "pwd" MongoAuthenticationDatabase = "gridfs" mongodbUri = "" if MongoUseAuth : mongodbUri = "mongodb://%s:%s@%s:%s/%s" % ( quote_plus(MongoUsername), \ quote_plus(MongoPassword), \ MongoHost, \ MongoPort, \ MongoAuthenticationDatabase \ ) #'mongodb://gridfs:N%40tur1ing@xxx:27017/gridfs' else: mongodbUri = "mongodb://%s:%s" % ( MongoHost, \ MongoPort ) #'mongodb://localhost:27017' #'mongodb://xxx:27017' mongoClient = MongoClient(mongodbUri)
方法2: 在MongoClient的参数中指定用户名,密码,要验证的数据库
mongoClient = MongoClient( host="xxx", port=27017, username="gridfs", password="pwd", authSource="gridfs" )
均可正常,用:用户名+密码+验证数据库,通过验证,后续可正常读写操作数据库。
心得:
之前不小心用:
mongodbUri = "mongodb://%s:%s@%s" % (quote_plus("gridfs"), quote_plus("pwd"), quote_plus("xxx:27017/gridfs"))
而把端口号连带要验证的数据库:
27017/gridfs
encode为:
27017%2Fgridfs
导致MongoClient内部以为port参数是
(27017%2Fgridfs 解码后的)
27017/gridfs
-》而不是正常的:27017
-〉从而导致报错:
ValueError: Port must be an integer between 0 and 65535: 27017/gridfs
-》提醒我们,对于mongo的uri中的其他的值,包括端口号和要验证的数据库等值,不要过度的,去编码本身不需要编码的值,从而导致出错。
-》正常的需要编码的,一般只有:
用户名和密码
尤其是密码,此处包含了非正常字符@,所以才要用到:
quote_plus(“P@wd”)
的。
-》其他没有包含特殊字符,包括此处上面的
quote_plus(“gridfs”)
其实完全没有必要,直接写成:
gridfs
就可以了。