Python/Django - 避免在源代码中保存密码
我用Python和Django来创建网页应用程序,并把它们存储在源代码管理中。通常情况下,Django的设置是把密码直接写在settings.py文件里,这样密码就是明文的。
把密码明文存储会带来很多安全问题,特别是因为这是一个开源项目,我的源代码会被版本控制(通过git,放在Github上,任何人都能看到!)
所以,问题是,在Django/Python开发环境中,怎样安全地写一个settings.py文件才是最佳做法呢?
4 个回答
这是一个老问题,提问的人我相信已经找到了解决办法。不过我自己在查这个问题时发现,这里的答案并没有完全解决我的疑问,所以我想分享一下我做的事情,可能会对其他有类似问题的人有帮助。
我做的就是使用getpass()这个功能,让设置文件在启动时询问密码。
from getpass import getpass
#[...]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', #or whatever DB you use
'NAME': 'mydb',
'USER': 'myuser',
'PASSWORD': getpass(),
'HOST': '',
'PORT': '',
}
}
虽然环境变量在很多配置上很方便,但把密码放在环境变量里是不安全的。如果选择使用一个不在常规版本控制下的配置文件,这里有一些缺点:
环境变量可能会意外泄露,比如通过调试信息,这些信息可能以明文形式传输给最终用户,或者被记录到一些意想不到的地方,比如文件系统中的 ~/.*sh_history。
配置文件可能会不小心被加入版本控制,最终被那些没有部署权限的人访问到。
想了解更多理由,可以看看这篇博客文章《环境变量对你的秘密来说是有害的》:环境变量对整个进程都是可访问的,会被子进程(甚至可能是第三方进程)继承,而且外部开发者并没有明确的假设认为环境变量是保密的。
在Python中,最简单的配置文件格式其实就是一个Python模块。
虽然我在StackOverflow上没找到专门针对Python的内容,但我找到了一些有用的网站,觉得可以分享给大家。这个网站的链接是这里。
解决方案是:环境变量。
注意:环境变量在Linux/Unix/OS X和Windows系统中都很相似,不过我没有在Windows机器上测试过这段代码。如果你在Windows上试过,请告诉我效果如何。
在你的bash/sh命令行中,输入:
export MYAPP_DB_USER='myapp'
export MYAPP_DB_PASSWORD='testing123'
然后在你的Django的settings.py文件中:
DATABASE_USER = os.environ.get("MYAPP_DB_USER", '')
DATABASE_PASSWORD = os.environ.get("MYAPP_DB_PASSWORD", '')
在这种情况下,如果环境变量不存在,用户名和密码会默认设置为空字符串。