【问题标题】:Django, Security and SettingsDjango,安全和设置
【发布时间】:2017-06-23 23:17:01
【问题描述】:

来自here,我们将所有数据库信息添加为文本:

DATABASES = {
'default': {
    'ENGINE': 'django.db.backends.postgresql',
    'NAME': 'mydatabase',
    'USER': 'mydatabaseuser',
    'PASSWORD': 'mypassword',
    'HOST': '127.0.0.1',
    'PORT': '5432',
    }
 }

这是一种安全的方式吗?有没有办法将此数据保存为加密数据?

【问题讨论】:

    标签: python django security encryption


    【解决方案1】:

    这并不安全,任何有权访问您的源代码控制的人现在都可以访问您的数据库。

    存储敏感数据的两种主要方法是使用环境变量或通过 json 文件


    摘自Settings - Hiding secret data using a JSON file。原作者是Antoine Pinsardfredley。归属细节可以在contributor page 上找到。该源在CC BY-SA 3.0 下获得许可,可以在Documentation archive 中找到。参考主题 ID:942 和示例 ID:8734。

    使用 JSON 文件隐藏机密数据

    在使用诸如 Git 或 SVN 之类的 VCS 时,有一些机密数据永远不能进行版本控制(无论存储库是公共的还是私有的)。

    在这些数据中,您可以找到SECRET_KEY 设置和数据库密码。

    从版本控制中隐藏这些设置的常见做法是在项目的根目录 (thanks "Two Scoops of Django" for the idea) 创建一个文件 secrets.json

    {
        "SECRET_KEY": "N4HE:AMk:.Ader5354DR453TH8SHTQr",
        "DB_PASSWORD": "v3ry53cr3t"
    }
    

    并将其添加到您的忽略列表中(.gitignore 用于 git):

    *.py[co]
    *.sw[po]
    *~
    /secrets.json
    

    然后将以下函数添加到您的settings 模块:

    import json
    import os
    from django.core.exceptions import ImproperlyConfigured
    
    with open(os.path.join(BASE_DIR, 'secrets.json')) as secrets_file:
        secrets = json.load(secrets_file)
    
    def get_secret(setting, secrets=secrets):
        """Get secret setting or fail with ImproperlyConfigured"""
        try:
            return secrets[setting]
        except KeyError:
            raise ImproperlyConfigured("Set the {} setting".format(setting))
    

    然后以这种方式填写设置:

    SECRET_KEY = get_secret('SECRET_KEY')
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgres',
            'NAME': 'db_name',
            'USER': 'username',
            'PASSWORD': get_secret('DB_PASSWORD'),
        },
    }
    

    致谢:Two Scoops of Django: Best Practices for Django 1.8, by Daniel Roy Greenfeld and Audrey RoyGreenfeld. Copyright 2015 Two Scoops Press (ISBN 978-0981467344)


    摘自Settings - Using Environment variables to manage Settings across servers。原作者是sudshekharssiceNBajanca。归属细节可以在contributor page 上找到。该源在CC BY-SA 3.0 下获得许可,可以在Documentation archive 中找到。参考主题 ID:942 和示例 ID:3580。

    使用环境变量跨服务器管理设置

    The Twelve-Factor App 所述,使用环境变量是一种广泛使用的根据应用环境设置应用配置的方法。

    由于部署环境之间的配置可能会发生变化,因此这是一种非常有趣的方式来修改配置,而无需挖掘应用程序的源代码,以及在应用程序文件和源代码存储库之外保密。

    在 Django 中,主要设置位于项目文件夹中的settings.py。由于它是一个简单的 Python 文件,因此您可以使用标准库中 Python 的 os 模块来访问环境(甚至具有适当的默认值)。

    settings.py

    ​​>
    import os
    
    SECRET_KEY = os.environ.get('APP_SECRET_KEY', 'unsafe-secret-key')
    
    DEBUG = os.environ.get('DJANGO_DEBUG', "True") == "True"
    
    ALLOWED_HOSTS = os.environ.get('DJANGO_ALLOWED_HOSTS', '').split()
    
    DATABASES = {
        'default': {
            'ENGINE': os.environ.get('APP_DB_ENGINE', 'django.db.backends.sqlite3'),
            'NAME': os.environ.get('DB_NAME', 'db.sqlite'),    
            'USER': os.environ.get('DB_USER', ''),
            'PASSWORD': os.environ.get('DB_PASSWORD', ''),
            'HOST': os.environ.get('DB_HOST', None),
            'PORT': os.environ.get('DB_PORT', None),
            'CONN_MAX_AGE': 600,
        }
    }
    

    使用 Django,您可以更改您的数据库技术,以便您可以在您的开发机器上使用 sqlite3(这应该是提交到源代码控制系统的合理默认设置)。虽然这是可能的,但不建议这样做:

    后备服务(例如应用的数据库、排队系统或缓存)是开发/产品奇偶校验很重要的一个领域。 (The Twelve-Factor App - Dev/prod parity)

    【讨论】:

    • 加密数据呢?
    • @TheNone - 无论如何,如果你有一个更安全的解决方案,你会更舒服地使用它,那么就去吧。但是我从来没有发现需要比环境变量更安全的要求,因为我们的生产只锁定了最受信任的。我认为将解密与加密文件放在同一个地方没有意义
    • @TheNone 老实说,这是解决问题的错误方法。应该保密的设置——你的密钥、数据库凭据等——应该是你的部署本地的,所以正确的解决方案是让这些设置完全不受源代码控制。其他设置可以安全地存在于源代码控制中,无需任何加密。如果攻击者可以访问您的部署,而不仅仅是您的源代码控制,那么他的方法也不会增加任何安全性,因为实际部署应用程序需要明文文件。
    • 请更正您的调试:DEBUG = os.environ.get('DJANGO_DEBUG','True') == 'True'
    • 很好的答案。不过我想知道,为什么它没有被烘焙到 django 中。我不喜欢“自己去解决这个问题”的方法。我更喜欢开箱即用的 django,而不必跳过这么多圈
    【解决方案2】:

    感谢 Sayse 提出使用环境变量的绝妙想法。对于那些使用 Pycharm 连接到 mysql 数据库的用户,您需要创建一个 'USER' 环境变量并使用 os.environ.get('environment variable', '') 调用它避免将数据库密码存储在 settings.py 中。

    【讨论】:

      【解决方案3】:

      ,它不安全。

      您不得将这些信息上传到互联网。

      我经常做的是:

      • 在根目录下添加 env 文件。
        例如,如果项目名为 MYPROJECT
        env 文件的目录是 MYPROJECT/env

      • 将 env 文件添加到 .gitignore 文件。

      • 我使用数据库 url 形式,我发现它更优雅,而且行数更少。
        要使用它,请键入:

        • pip install dj_database_url

        • 将此行添加到 settings.py

          import dj_database_url

        • 那么简洁优雅就跟这种类型一样:
          DATABASES = { 'default': dj_database_url.config(default='postgres://user:password@localhost:5432/database_name'), }

      • 现在,用关键字替换 url,并将 url 安全地隐藏在 env 文件中,如:

        DATABASES = { 'default': dj_database_url.config(default=os.environ.get('DATABASE_URL')), }

        注意:这样你只输入了一次 os.environ.get()。

      • 转到 env 文件并添加
        export DATABASE_URL='postgres://user:password@localhost:5432/database_name'

      • 别忘了!让告诉终端这些关键字!在项目目录中输入终端:
        source env

      祝你好运。

      【讨论】:

        猜你喜欢
        • 2019-04-06
        • 1970-01-01
        • 2015-04-26
        • 1970-01-01
        • 2014-04-05
        • 2012-03-11
        • 1970-01-01
        • 1970-01-01
        • 2015-10-25
        相关资源
        最近更新 更多