Распространение проектов Django с уникальными ключами SECRET_KEY - PullRequest
49 голосов
/ 12 января 2011

У меня есть проект Django, который я хотел бы распространять в общедоступном репозитории, таком как bitbucket или github.Мне бы хотелось, чтобы его было как можно проще установить, поэтому я включаю весь проект, а не только подключаемые приложения.Это означает, что файл settings.py также будет включен.

Как можно избежать проблемы одинакового settings.SECRET_KEY для каждой установки?

Является ли единственный простым решение, чтобы пользователь вручную изменил settings.py?

Должен ли я сохранить ключ в базе данных по умолчанию и settings.py инициализировать его, если он не существует?Это решило бы проблему, но мне интересно, есть ли уже стандартный способ сделать это.

Спасибо!

Ответы [ 8 ]

76 голосов
/ 19 мая 2013

Чтобы добавить к сказанному Carles Barrobés , вы можете создать новый ключ, используя метод, который Django использует в startproject:

from django.utils.crypto import get_random_string

chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
get_random_string(50, chars)

Для Django 1.10 и выше, приведенный выше фрагмент кода хорошо обернут в функцию.

from django.core.management.utils import get_random_secret_key
get_random_secret_key()

Ссылка на репозиторий GitHub

39 голосов
/ 13 января 2011

Я бы поступил так:

Иметь секретный ключ в отдельном файле "secret_key.py".Этот файл не существует для первоначальной установки.В вашем файле settings.py есть что-то вроде:

try:
    from .secret_key import SECRET_KEY
except ImportError:
    SETTINGS_DIR = os.path.abspath(os.path.dirname(__file__))
    generate_secret_key(os.path.join(SETTINGS_DIR, 'secret_key.py'))
    from .secret_key import SECRET_KEY

Функция generate_secret_key(filename), которую вы напишете, генерирует файл с именем filename (который, как мы его называем, будет secret_key.py в том жеdir as settings.py) с содержанием:

SECRET_KEY = '....random string....'

Где случайная строка - это сгенерированный ключ, основанный на случайном числе.

Для генерации ключа вы можете использовать предложение Уманга https://stackoverflow.com/a/16630719/166761.

14 голосов
/ 04 ноября 2018

Откройте оболочку Django с помощью python manage.py shell и выполните следующие действия для создания безопасного случайного секретного ключа в Django 2.1:

>>> from django.core.management.utils import get_random_secret_key
>>> get_random_secret_key()
'[GENERATED KEY]'
>>>

Примечание: >>> представляет приглашение оболочки и не должно вводиться.

5 голосов
/ 12 января 2011

Вообще говоря, вы можете разделить конфигурацию Django на вещи, которые зависят от приложения, и вещи, которые зависят от сервера.Это относится ко второй категории.

Существует несколько способов решения проблемы конфигурации, специфичной для сервера, это обсуждается более подробно в этом вопросе .

.Для этого конкретного случая, используя подход, который я обрисовал в своем ответе на другой вопрос, я бы поместил заполнитель в settings_local.py.sample для распространения, а во время установки скопировал бы его в settings_local.py и отредактировал бы в соответствии с требованиями.

2 голосов
/ 19 мая 2014

Я бы решил эту проблему так:

  • Укажите фиктивный секретный ключ, например: I_AM_A_DUMMY_KEY_CHANGE_ME
  • Создайте команду управления для создания новой команды: ./manage.py gen_secret_key
  • В документации настоятельно советуем пользователям запускать команду как можно скорее
1 голос
/ 12 июня 2014

В моем коде у меня есть три уровня файла настроек, вдохновленные Two Scoops of Django, поэтому средний идет так, где BASE_PRIVATE_DIR установлен в базовом шаблоне.В моем случае это из каталога django ../../mysite_private, но где-то в стороне от обычных файлов в приложении git.:

from .base import *

ALLOWED_HOSTS = ['staging.django.site'] 
#Allow local override which is per deployment instance.  There should probably then be
#  an instance git for version control of the production data
try:
    import sys
    private_path = BASE_PRIVATE_DIR.child('production')
    sys.path.append(private_path)
    from private_settings import *
except ImportError:
    print(" No production overide private_settings.py found.  This is probably an error  = {}".format(private_path))
    # If it doesnt' exist that is fine and just use system and environment defaults
0 голосов
/ 19 марта 2018

В этом решении я использую django-dotenv , который является одной из зависимостей моего проекта, как указано в requirements.txt как django-dotenv==1.4.1. Преимущество этого подхода в том, что у вас есть отдельный файл .env для каждой среды, в которой установлено приложение.

Создайте файл utils.py в том же каталоге settings.py со следующим содержимым:

from django.utils.crypto import get_random_string

def generate_secret_key(env_file_name):
    env_file = open(env_file_name, "w+")
    chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
    generated_secret_key = get_random_string(50, chars)
    env_file.write("SECRET_KEY = '{}'\n".format(generated_secret_key))
    env_file.close()

Затем измените файл settings.py следующим образом:

import dotenv
from [project-folder-name] import utils
...
try:
    SECRET_KEY = os.environ['SECRET_KEY']
except KeyError:
    path_env = os.path.join(BASE_DIR, '.env')
    utils.generate_secret_key(path_env)
    dotenv.read_dotenv(path_env)
    SECRET_KEY = os.environ['SECRET_KEY']

Для тех, кто не использует django-dotenv, все, что вам нужно сделать, это добавить его в качестве зависимости и изменить manage.py, чтобы загрузить его при запуске:

import dotenv

if __name__ == "__main__":
    dotenv.read_dotenv()
0 голосов
/ 21 июня 2016

Если вы создаете новый проект с использованием шаблона, например django-admin.py startproject --template=path_to_template project_name, просто поместите {{ secret_key }} в файл настроек шаблона вашего проекта (например, settings.py), например SECRET_KEY = '{{ secret_key }}', и Django создаст его для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...