일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- web
- migrate
- restfulapi
- 사용자인증
- restapi
- 장고
- PYTHON
- virtual environment
- 서버설계
- djangorest
- migrations
- 파이썬
- API
- resful
- rest framework
- django 시간 설정
- SOAP API
- restful
- http
- secretkey
- 서버구동
- 서버 만들기
- 웹
- 분리설정
- 환경분리
- 환경설정하기
- REST
- server
- url
- Django
- Today
- Total
grape
[Django 02] - 시크릿 키(SECRET_KEY) 분리 설정 본문
시크릿 키란? (SECRET_KEY)
장고 프로젝트를 생성하면, 기본적으로 메인 폴더에 settings.py가 생성된다. settings.py 안에는 다양한 설정 항목들이 있는데 그중 SECRET_KEY라는 것이 있다. Django 공식문서를 보면 다음과 같이 안내 되어 있다.
- SECRET_KEY의 사용 용도
- django.contrib.sessions.backends.cache 이외의 session backend를 사용하고 있거나, 기본 get_session_auth_hash()를 사용하는 모든 sessions
- CookieStorage 혹은 FallbackStorage를 사용하는 모든 messages
- 모든 PasswordResetView
- 다른 키가 제공되지 않는 암호화 서명 사용 시 사용된다.
"SECRET_KEY 란 특정 django 설치을 위한 비밀 키이며 이는 암호화 서명을 제공하는 데 사용되며 고유하고 예측할 수 없는 값으로 설정해야 한다. "라고 나와 있다. 즉, 암호화 인증에 사용되는 비밀키라는 말이다. - (보안 관리)
그리고 SECRET_KEY는 공개하면 안된다 !
공식문서에서 위 문서와 같이 비밀 키가 노출되면 Django의 보안 기능이 상실될 위험성이 있다고 안내되어 있다.
Tip.
SECRET_KEY는 프로젝트 생성 시 자동으로 생성되며 해당 값은 예측할 수 없는 값이며 유일한 값으로 세팅된다. 또한 버전 컨트롤 시스템(Git)에서 제외되어야 하며 만약 외부에 노출 시 보안 위협에 노출될 수 있기 때문에 settings.py 파일이 아닌 외부에 따로 저장해야 한다. SECRET_KEY 말고도 AWS 시크릿 코드 등의 비밀 값들이 있는데 이런 비 밀값들은 프로젝트 코드에 포함되면 안 된다. 이러한 비밀 값들은 별도의 JSON 파일 또는 라이브러리(ex - environ) 파일로 보관하고, 해당 값들을 django에서 불러오는 방법으로 사용한다.
-- SECRET_KEY가 없으면 Django 프로젝트는 실행되지 않는다.
-- 해당 키를 분리하는 방법으로는 환경 변수를 이용한 방법과 외부에 저장하는 방법 2가지가 있다.
- 환경변수 패턴: SECRET_KEY의 값을 환경변수에 저장하여 참고한다.
- 비밀파일 패턴: SECRET_KEY의 값을 별도 파일에 저장하여 참고한다.
SECRET_KEY 배포 후 변경 가능 유무
SECRET_KEY 같은 경우 한번쯤은 공개 저장소에 올린 적이 있을 것이다. 하지만 다행히도 배포 후 에도 SECRET_KEY 변경이 가능하다는 글이 있다.
SECRET_KEY는 50자의 랜덤 문자로 구성되어 있는데, Django Secret Key Generator라는 것도 존재하고 혹은 아래의 코드를 실행해서 임의 50글자를 직접 생성하는 것도 가능하다. (코드 출처)
import string, random
# Get ascii Characters numbers and punctuation (minus quote characters as they could terminate string).
chars = ''.join([string.ascii_letters, string.digits, string.punctuation]).replace('\'', '').replace('"', '').replace('\\', '')
SECRET_KEY = ''.join([random.SystemRandom().choice(chars) for i in range(50)])
print(SECRET_KEY)
외부에 저장하는 방법
01. secret.json 생성
- 프로젝트 구조
tistory
|
|
| ㅡㅡ tistory (app 1)
| |
| |ㅡㅡ __init__.py
| |ㅡㅡ asgi.py
| |ㅡㅡ settings.py
| |ㅡㅡ urls.py
| |____ wsgi.py
|
|
| ㅡㅡ blog (app 2)
| |
| |ㅡㅡㅡㅡㅡ migrations
| | |
| | |___ __init__.py
| |ㅡㅡ __init__.py
| |ㅡㅡ admin.py
| |ㅡㅡ apps.py
| |ㅡㅡ models.py
| |ㅡㅡ tests.py
| |____ views.py
|
|
| ㅡㅡㅡ db.sqlite3
| ㅡㅡㅡ secrets.json
|______ manage.py
프로젝트 구조를 보면 알 수 있듯이 secrets.json 파일을 생성하는데 생성하는 위치는 프로젝트 컨테이너 폴더에서 생성해 주면 된다.
02. secrets.json 내용
{
"SECRET_KEY": "<Your Django SECRET KEY>"
}
위와 같이 Json 형식에 맞게 settings.py에 생성된 SECRET_KEY를 가져와서 secrets.json 파일에 저장해 준다.
secret_key 이외에 데이터 베이스 ID, PW 값 등등 보안에 문제 될 수 있는 내용 또한 secrets.json 파일에 따로 분리 저장할 수 있다.
03. settings.py
import os, json
from django.core.exceptions import ImproperlyConfigured
BASE_DIR = Path(__file__).resolve().parent.parent
secret_file = os.path.join(BASE_DIR, 'secrets.json') # secrets.json 파일 위치를 명시
with open(secret_file) as f:
secrets = json.loads(f.read())
def get_secret(setting):
"""비밀 변수를 가져오거나 명시적 예외를 반환한다."""
try:
return secrets[setting]
except KeyError:
error_msg = "Set the {} environment variable".format(setting)
raise ImproperlyConfigured(error_msg)
SECRET_KEY = get_secret("SECRET_KEY")
위 코드를 보면 알 수 있듯이 os, json 모듈을 먼저 import 해준다. 그다음 BASE_DIR 코드를 상위로 올려준다. 그 이유는 파이썬의 코드 동작 순서는 위에서 아래로 동작하기 때문에 먼저 BASE_DIR 현재 최상위 파일 위치(tistory)를 잡아준다.
그다음 secret_file이라는 변수에 screts.json 파일을 담아 준 뒤 해당 파일을 열어서 secrets이라는 변수에 담아 준다.
get_secret 함수를 생성해서 비밀 변수를 가져오거나 예외를 발생시키는 함수를 생성 한 뒤 이를 이용해서 SECRET_KEY에 사용하므로 써 외부의 노출을 막아 준다.
04. gitignore 파일에 추가
# .gitignore 파일
secrets.json
.gitignore 파일에 secrets.json 파일을 추가해서 비 밀값들이 커밋에 포함되지 않도록 설정한다.
- gitignore 파일의 위치는 screts.json과 같은 위치에 위치시켜주면 된다.
. gitignore 파일이란?
사용자가 원하지 않는 파일들을 자동적으로 git 커밋 대상에서 제외시켜주는 파일이다.
프로젝트를 진행하다 보면 git에 올려서는 안 되거나 불필요한 파일이 있다.
자동 생성 파일들은 코드만 있으면 그때그때 실행할 수 있어 굳이 Github 용량을 차지할 필요가 없고 또한 보안적으로 중요한 내용이 담긴 파일은 오픈소스로 공개되면 곤란하다. 이때. gitignore파일 안에 이들을 넣어서 관리하는 것이다.
커밋 대상에서 제외시켜야 할 것들
- IDE tool과 관련된 설정 파일
- 언어의 빌드 결과물, 로그, 패키지 관련 파일
- 그 외 프로젝트에서 사용자가 제외하기 원하는 파일 등등..
정리
AWS 루트키, SECRET_KEY, DB 정보 등등 보안 관련 이슈들은 배포 전에 분리하는 것이 가장 좋으며 그에 따른 부작용이 발생할 수 있으니 프로젝트 생성 후 처음부터 관리하는 게 좋다.
만약 이미 기존 커밋에 비 밀값들이 포함된 상태라면, 커밋 이후에 비 밀값들을 제외하다록 하여도 기존 커밋에는 내용이 남아 있다. 이때는 git의 reset 명령어로 비밀값이 포함된 커밋을 삭제해야 하며, 또 커밋이 공개 저장소에 push된 상태라면 서비스 프로바이더(페이스북, AWS 등등 ...)에서 해당 비밀값들을 모두 재설정해야 한다.
참고
https://wayhome25.github.io/django/2017/07/11/django-settings-secret-key/
'웹 프로그래밍 > Django' 카테고리의 다른 글
[Django 03] - Django 한국 시간 설정 (1) | 2021.06.06 |
---|---|
[Django 01] - 동작 원리 및 기본 설정 (0) | 2021.05.27 |
Django로 RESTful API 서버 설계하기 (5) (0) | 2021.05.24 |
Django로 RESTful API 서버 설계하기 (4) (0) | 2021.05.23 |
Django로 RESTful API 서버 설계하기 (3) (0) | 2021.05.20 |