장고 프로젝트를 시작하면 기본 settings.py
내부에 이런 코드가 들어있다.
1
2
3
# settings.py
SECRET_KEY = 'SECTRET KEY'
Django에서 서버를 동작할 때 사용하는 비밀 키가 들어있는데, 문제는 해당 프로젝트를 github에 업로드 하면 너도나도 모두가 비밀 키를 확인할 수 있다.
물론 간단하게 하는 프로젝트나 연습용에는 보안이 크게 상관은 없겠지만 이것 또한 습관이라고 언제나 보안에 신경 쓸 필요가 있다 생각한다.
그럼 github에 업로드는 하는데, 해당 코드만 따로 쏙 빼거나 관리할 수 없을까? 해서 나온 라이브러리가 Django_Environ 이라 생각하면 편하다.
사용하기
인스톨
가상환경 내에서 장고를 인스톨 한 후, environ을 인스톨 한다.
1
2
3
4
5
$ pip install django
$ pip install django-environ
$ pip freeze
1
2
Django==4.2.5
django-environ==0.11.2
2023년 09월 10일 현재 최신버전은 0.11.2
라고 한다.
.env 설정하기
가끔 gitignore
파일을 뜯어보면 .env
가 자동으로 들어있을 때가 있다.
그 녀석이 맞다.
환경 변수들을 모아놓은 것으로, 해당 파일에서 관리해 보안을 높일 수 있고 관리하기도 편하다.
Django Environ Quick Start를 보면 아래와 같은 코드를 제공한다.
1
2
3
4
5
6
DEBUG=on
SECRET_KEY=your-secret-key
DATABASE_URL=psql://user:un-githubbedpassword@127.0.0.1:8458/database
SQLITE_URL=sqlite:///my-local-sqlite.db
CACHE_URL=memcache://127.0.0.1:11211,127.0.0.1:11212,127.0.0.1:11213
REDIS_URL=rediscache://127.0.0.1:6379/1?client_class=django_redis.client.DefaultClient&password=ungithubbed-secret
해당 코드는 Root Directory
즉 따로 설정하지 않았다면 manage.py
가 있는 디렉토리에 .env
라는 파일을 생성해 입력한다.
1
2
3
# Root Directory 이동 후(따로 설정 안했다면 manage.py가 있는 곳)
touch .env
해당 폴더에 위 코드를 복사한 후, 알맞게 채워주자.
1
2
3
4
# settings.py 내부. 해당 키는 아무거나 작성한거다.
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-0)qwdqwdas'
1
2
3
4
# .env
DEBUG=on
SECRET_KEY=django-insecure-0)qwdqwdas
이런 식으로 넣어주면 된다.
Settings.py 작성하기
이제 민감한 정보들은 모두 옮겼으니 github에 커밋 될 settings.py
를 다시 작성 해보자.
일단 Django-Environ
의 QuickStart 에서는 해당 가이드라인을 제공한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import environ
import os
env = environ.Env(
# set casting, default value
DEBUG=(bool, False)
)
# Set the project base directory
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Take environment variables from .env file
environ.Env.read_env(os.path.join(BASE_DIR, '.env'))
# False if not in os.environ because of casting above
DEBUG = env('DEBUG')
# Raises Django's ImproperlyConfigured
# exception if SECRET_KEY not in os.environ
SECRET_KEY = env('SECRET_KEY')
# Parse database connection url strings
# like psql://user:pass@127.0.0.1:8458/db
DATABASES = {
# read os.environ['DATABASE_URL'] and raises
# ImproperlyConfigured exception if not found
#
# The db() method is an alias for db_url().
'default': env.db(),
# read os.environ['SQLITE_URL']
'extra': env.db_url(
'SQLITE_URL',
default='sqlite:////tmp/my-tmp-sqlite.db'
)
}
CACHES = {
# Read os.environ['CACHE_URL'] and raises
# ImproperlyConfigured exception if not found.
#
# The cache() method is an alias for cache_url().
'default': env.cache(),
# read os.environ['REDIS_URL']
'redis': env.cache_url('REDIS_URL')
}
settings.py
를 유심히 봤으면 알겠지만 해당 코드들은 기존 내용을 조금씩 변경한 것들이다.
다른 설정은 가능하면 건들지 말고 해당 코드들만 붙여넣는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# settings.py에 코드 적용한 모습(예시)
"""
Django settings for TransitInsights project.
Generated by 'django-admin startproject' using Django 4.2.4.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""
import environ
import os
from pathlib import Path
env = environ.Env(
# set casting, default value
DEBUG=(bool, False)
)
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Take environment variables from .env file
environ.Env.read_env(os.path.join(BASE_DIR, '.env'))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env.str('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'FirstApp',
'SecondApp'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'ROOT.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'ROOT.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = [
BASE_DIR / 'static',
]
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
이렇게 적용하면 .env
파일을 가지고 있는 로컬에서는 동작 하지만, 일반 github에서 clone 한 사용자는 접속이 불가능 한 모습을 볼 수 있다.
주의!
Django-Environ
에서 기본 제공하는 BASE_DIR는 str 타입으로 출력된다.
가끔 DATABASE 등 패스타입으로 제공받아야 하는 코드들이 충돌을 일으키니 주의하자.
주의2!
1
2
3
4
# .env
DEBUG=on
SECRET_KEY=django-insecure-0)qwdqwdas
여기서
=
앞 뒤로 띄어쓰기 하지 않기- 값 넣을때
' '
사용하지 않기.