현대 웹 애플리케이션에서 프론트엔드와 백엔드가 별도의 도메인으로 운영되는 경우, 클라이언트가 다른 도메인으로 요청을 보낼 때 브라우저는 기본적으로 보안상의 이유로 요청을 차단합니다. 이 현상을 '크로스 오리진 문제'라고 하며, 이를 해결하기 위해 CORS (Cross-Origin Resource Sharing) 표준이 도입되었습니다.
CORS는 브라우저와 서버 모두가 지원해야 하는 기술이며, 대부분의 현대 브라우저(IE10 이상)에서는 자동으로 처리됩니다. 개발자 입장에서는 일반적인 AJAX 요청과 동일한 코드로 작성할 수 있으며, 브라우저가 자동으로 추가 헤더를 삽입하거나 사전 검사를 수행합니다.
요청 유형 구분
- 간단 요청 (Simple Request): GET, POST, HEAD 중 하나이며, 헤더에 다음 제한된 항목만 포함 가능.
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type: application/x-www-form-urlencoded, multipart/form-data, text/plain 만 허용
Access-Control-Allow-Origin헤더만 포함하면 됩니다. - 복잡 요청 (Complex Request): 위 조건을 벗어나는 모든 요청입니다. 브라우저는 먼저
OPTIONS요청을 보내 사전 검증을 수행하며, 이 과정을 preflight라 합니다.
기본 해결 방식: 응답 헤더 설정
서버 응답에 다음 헤더를 포함하면 크로스 오리진 요청을 허용할 수 있습니다:{
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS"
}
> 주의: *는 모든 도메인을 허용하지만, 인증 정보가 필요한 경우 사용 불가. 실제 서비스에서는 특정 도메인만 허용하는 것이 안전합니다.
Django 프로젝트에서의 구현
Django 프로젝트에서는django-cors-headers 패키지를 활용해 간편하게 설정할 수 있습니다.
- 설치:
pip install django-cors-headers - 설정 파일에 등록:
# settings.py INSTALLED_APPS = [ # ... 'corsheaders', # ... ] MIDDLEWARE = [ # ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', # ... ] - 보안 설정:
CORS_ORIGIN_ALLOW_ALL = False # 모든 도메인 허용 금지 CORS_ORIGIN_WHITELIST = [ 'http://localhost:3000', 'https://myapp.com' ] CORS_ALLOWED_METHODS = [ 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS' ] CORS_ALLOWED_HEADERS = [ 'Content-Type', 'Authorization', 'X-Requested-With', 'X-CSRFToken', 'token' ]