前言
前几天因为使用MongoDB没有设置严格的登陆用户名密码,只设置了固定IP可以访问。结果还是被扫描到了,然后数据就被黑了,都丢了。然后黑客还让我缴纳0.6个比特币……
还好数据有备份,虽然时间早了点儿。。。哎。。。经过这次事件,**真的,以后用MongoDB真的要养成设置密码的习惯啊!!!**
版本信息
遇到的问题
网站使用Flask开发的,使用Python的时候我习惯配套MongoDB一起使用。我选择的是Flask-Pymongo而不是Flask-MongoEngine。因为因为我开发网站一般都是选择(其实是百分百)前后端分离的方式,前端用Vue,后台接啥都行,然后通过Ajax调用。
而Flask-MongoEngine更像模板渲染的方式的,不符合我的要求,还要定义各种Field,像ORM一样。所以相比之下,我还是感觉Flask-Pymongo更灵活一些。
在MongoDB中,首先要创建一个用户,然后这个用户是在admin数据库中创建的,所以创建好了之后,要先“use admin”,然后进行auth:“db.auth(“your_username”, “your_password”)”。
在pymongo的话,就可以通过下面的方式,先使用client.admin.authenticate进行验证,这个步骤是在admin数据库进行的,然后再连接到别的数据库your_db。
1 | client = pymongo.MongoClient() |
然而在Flask-Pymongo封装后,文档说明如下:
其中没有发现有用于验证的数据库,然后我进行了如下的配置:
1 | app = Flask(__name__) |
而后出现了“pymongo.errors.OperationFailure: auth failed”的错误
然后这个时候,我把MONGO_DBNAME改为admin。
1 | app.config['MONGO_DBNAME'] = "admin" |
发现auth通过了,但是没数据了。因为连接的是admin数据库,而不是your_db。
源码分析
这里为了一探究竟,使用了PyCharm的自动跳转功能查看一下Flask-Pymongo配置部分的源码。初始化部分在init_app方法中。
可以看到这里面最开始用于验证的数据库就是admin,然后这里的if条件不成立,看下else是什么样子的。
这里可以看到,如果我们配置了MONGO_DBNAME,这里就会改变auth_database。
再往下看,我们可以看到这里MONGO_DBNAME如果没有设置的话,就会被设置成app.name。当然如果我们设置了MONGO_DBNAME,用于验证和连接的数据库都会变成MONGO_DBNAME。
所以经过分析,我们可以不使用MONGO_DBNAME,然后让DBNAME通过app.name来进行设置。
解决方法
最后的解决方法如下:
1 | app = Flask(__name__) |
总结
有的时候看看源码还是蛮有用的,框架的源码不一定就很复杂。