我们开发的每一个系统都离不开配置信息,比如数据库密码,Redis密码,邮箱配置,各种第三方配置信息,这些信息都是非常敏感的,一旦泄露,后果将非常严重。被泄露的原因一般是程序员将配置信息和代码混在一起造成的。判断系统是否正确地将配置保留在代码之外的一种简单方法是查看该系统的代码是否可以立即开源而不用担心暴露任何敏感信息。所以我们首先要做的是将配置信息与代码解耦,根据不同的部署环境(开发环境、测试环境、预发布、生产环境)使用一套配置文件,然后将配置信息集中到配置文件中间。比如django的最佳实践中,就有这样的实践。每个部署环境都有一个独立的配置文件,因为每个部署环境需要的配置都不一样。├──settings│├──__init__.py│├──base.py│├──local.py│├──production.py│└──test.py系统启动时,根据指定环境变量加载哪个配置文件。if__name__=="__main__":os.environ.setdefault("DJANGO_SETTINGS_MODULE","settings.local")到此结束了吗?不会,因为配置信息还是和项目代码捆绑在一起,如果把配置文件和代码同步到版本控制系统,还有敏感信息泄露的顾虑。之前只是将配置与代码解耦,但代码并没有与敏感的配置信息完全隔离。更好的方法是将配置存储在环境变量中。无需移动一行代码就可以在不同的部署之间轻松修改环境变量,并且将此信息同步到代码库的可能性很小。在代码中,我们通过读取环境变量中的配置信息来获取这个值。settings.pyMAIL_SERVER=os.getenv('MAIL_SERVER')MAIL_USERNAME=os.getenv('MAIL_USERNAME')MAIL_PASSWORD=os.getenv('MAIL_PASSWORD')现在即使代码开源了,也没有人知道密码是多少。有几种方法可以将配置信息保存在变量环境中。一种是手动在命令行上一个一个设置环境变量,类似:EXPORTSECRET_KEY=xxxxxEXPORTSQLALCHEMY_DATABASE_URI=XXXXEXPORTACCESSKEYID=XXXXX这种方法很麻烦,每次启动都需要设置,虽然也可以写到一个.bashrc之类的文件。第二种方式是在supervisor中写入配置信息。如果你的系统使用supervisor来管理进程,可以在supervisor中设置环境变量,如:[program:xxxx]environment=KEY=value,Key2=value2,key3="val.&"但是这个方法是耦合的使用主管自己的配置,使用起来很混乱。今天推荐的工具python-dotenv可以完全独立于其他配置,只针对应用本身使用的配置信息,只需要将所有的配置信息写入项目根目录下的.env文件即可,例如:REDIS_ADDRESS=localhost:6379MEANING_OF_LIFE=42MULTILINE_VAR="hello\nworld"我们不把这个文件放在git版本控制系统中。然后使用一行代码将配置信息加载到环境变量中#settings.pyfromdotenvimportload_dotenvload_dotenv()加载完成后,就可以使用os.getenv方法获取所有的配置信息了。#settings.pyimportosSECRET_KEY=os.getenv("EMAIL")DATABASE_PASSWORD=os.getenv("DATABASE_PASSWORD")这样就把敏感信息和代码完全分离了,代码和配置也解耦了。python-dov的安装可以用普通的pip安装。pipinstall-Upython-dotenv在django和flask应用开发中很常见,他们也基于这个库做了自己的扩展。例如,它可以在flask中使用.flaskenv而不是.env文件。没有任何
