CORS란 Cross-Origin Resource Sharing의 약자로, 서로 다른 출처(origin) 간에 자원을 공유할 수 있도록 하는 메커니즘이다. 브라우저에서는 보안상의 이유로 동일 출처 보안 정책(Same-Origin Policy)을 따르는데, 이는 다른 출처에서 온 요청에 대한 자원 접근을 제한한다. CORS는 이 정책을 우회하고 다른 출처 간의 통신을 가능하게 한다.
출처(origin)는 Protocal, Host, Port의 조합을 의미한다. 세가지 요소 중 하나라도 다르다면 다른 출처이다.
프리플라이트 요청은 실제 요청 전에 브라우저가 보내는 추가적인 요청이다. 주로 브라우저가 서버에게 실제 요청을 보내기 전에 해당 요청이 안전한지 여부를 확인하기 위해 사용된다.
프리플라이트 요청의 흐름은 다음과 같다.

OPTIONS 메서드를 사용하여 서버에게 프리플라이트 요청을 보낸다.Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers 등의 CORS 관련 헤더를 포함하여 응답한다.단순 요청은 프리플라이트 요청을 거치지 않고 직접 서버에게 보내는 요청이다. 이는 브라우저가 복잡한 요청이 아니라고 판단하는 경우에 발생한다.
단순 요청은 아래의 상황에서 발생한다.
GET, POST, HEAD 중 하나여야 한다.Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width만 사용할 수 있다.Content-Type 헤더는 application/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나를 사용해야 한다.단순 요청의 흐름은 다음과 같다.
Django 앱에서 CORS 헤더를 쉽게 관리할 수 있도록 하기 위해 아래의 패키지를 설치한다.
pip install django-cors-headers
현재 진행 중인 프로젝트는 설정을 base.py, dev.py, prod.py 각각으로 나눠서 진행 중이다. base.py의 내용을 각 환경의 설정 파일에서 import 후 추가적인 설정을 한다.
설정 파일에 패키지 추가해야 한다. base.py(settings.py) 파일에 corsheaders를 앱에 추가하고, 미들웨어를 등록한다.
INSTALLED_APPS = [
...
'corsheaders',
...
]
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
참고로 CorsMiddleware는 반드시 CommonMiddleware보다 위에 위치해야 한다.
dev 환경에서는 다양한 출처에서 요청을 테스트할 수 있는 유연성을 제공해야 하기 때문에 모든 출처(origin)에서 오는 요청들을 허용한다. 아래의 설정을 추가한다. 참고로 default 설정은 False이다.
CORS_ORIGIN_ALLOW_ALL = True
운영 환경에서는 CORS_ALLOWED_ORIGINS 설정을 통해 해당 서버에 요청을 할 수 있는 origin을 명시할 수 있다. 아래와 같이 uri scheme, hostname, port를 조합하여 명세한다.
CORS_ALLOWED_ORIGINS = [
"https://example.com",
"https://www.example.com",
"http://www.example.com",
]
추가적인 설정을 통해 Cross-Origin Resource Sharing (CORS) 정책을 더 세부적으로 제어할 수 있다. 이러한 설정은 특정 HTTP 메소드와 헤더에 대한 접근을 제한하여 웹 애플리케이션의 보안을 강화할 수 있다.
아래는 위에서 언급한 설정의 기본값이다. 추가적인 허용 및 제한을 위하여 설정 파일에 새로 작성하여 기존의 기본 설정을 덮어쓸 수 있다.
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
)
CORS_ALLOW_HEADERS = (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
)
참고 자료
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS#%EA%B8%B0%EB%8A%A5%EC%A0%81_%EA%B0%9C%EC%9A%94