본문 바로가기
개발/네트워크

CORS 에러 - ‘Access-Control-Allow-Headers’ 관련 오류

by Byeongdori 2022. 5. 22.
반응형

[해당 포스트는 Django 기준으로 설명하고 있습니다.]

 

'Access-Control-Allow-Headers' 오류

개발이 잘 된다 싶으면 마주하게 되는 CORS 오류, 매번 봐도 적응이 안 된다. 

 

CORS 정책에 대해 간단히 알아보고, 오류 원인, 해결방법에 대해 소개합니다.


CORS 정책이란?

  • 교차 출처 리소스 공유(Cross-Origin Resource Sharing)의 약자로, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 자원에 접근할 수 있는 권한을 부여하는 매커니즘을 의미합니다.
  • 출처(Origin)이란, 
    • https://127.0.0.1:3000/users?id=1과 같은 URL에서, 서버의 위치를 찾기 위한 기본적인 정보
    • 즉, 프로토콜, 호스트, 포트번호까지인 https://127.0.0.1:3000을 의미합니다.
  • 따라서 CORS 정책이란 다른 출처 사이의 통신을 위한 기본적인 규칙이라고 할 수 있습니다. 

CORS 통신 방식

  • 웹 클라이언트에서 다른 출처의 리소스를 요청할 때에는, 기본적으로 HTTP 프로토콜을 이용해 요청을 보내게 됩니다. 이때 Origin 필드를 사용하여, 헤더에 자신의 출처를 담아 보내게 됩니다.
  • 서버에서는 요청을 받으면, Access-Control-Allow-origin 필드를 사용하여, 서버 리소스에 접근이 허용된 출처들을 헤더에 실어 응답으로 다시 넘겨 보내게 됩니다.
  • 다시 응답을 받은 웹 클라이언트는 자신이 처음에 보낸 출처와, 받은 응답에서의 Access-Control-Allow-Origin 헤더를 비교한 후 리소스를 접근 할 수 있는지 판단합니다. 
    • 이 과정에서 발생하는 오류는 "Access-Control-Allow-Origin" header 오류입니다.
    • 이 과정까지는 예비 요청 - 응답으로 이루어집니다.
  • 리소스 접근이 가능하다면, 다시 본 요청을 보내 리소스 접근을 시도합니다.
  • 서버에서는 본 요청을 검토한 후, 원하는 리소스를 다시 응답으로 내려주게 됩니다.
    • 이번 포스팅에서 발생한 오류는, "서버에서 본 요청을 검토"하는 과정에서 발생합니다.

오류 발생 원인

  • 서버에서 본 요청을 검토할 시, 서버는 이 요청의 HTTP Method, Cookie 포함여부, HTTP 헤더 목록을 검사합니다.
  • 검사 과정에서 접근이 허락되지 않은 HTTP Method, Cookie, HTTP 헤더가 발견된 경우, 정책 위반 오류로 차단합니다.

    "Access to XMLHttpRequest at .. Request header field content-type is not allowed by

     Access-Control-Allow-Headers in preflight response."

    즉, 이번 오류는 HTTP 헤더와 관련하여 허용되지 않은 헤더가 요청으로 보내져, 정책 위반 오류가 발생해 차단된 경우입니다.

 

-  해결 방안

 간단합니다. 서버 측에서, 클라이언트가 보내는 헤더를 허용해주면 됩니다.

 

 이번 오류는 허용되지 않은 헤더에서 발생한 오류이지만, 4번 과정에서 오류 메세지에 맞게 설정을 조작하면 됩니다.

 

 1. django-cors-headers 설치

pip install django-cors-headers

 

 2. installed apps 목록에 corsheaders 추가

INSTALLED_APPS = [
    '''
    "corsheaders",
    '''
]

 

 3. middleware class 추가

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    ...
]

 

 4. Django settings.py로 이동하여, CORS 관련 설정 구성 

CORS_ORIGIN_WHITELIST = (	# 요청을 보낼 수 있는 출처들의 리스트를 정의합니다.
   "https://example.com",
)

CORS_ORIGIN_ALLOW_ALL = True # 모든 출처들을 허용합니다. (권장 X)

CORS_ALLOW_CREDENTIALS = True # 쿠키가 요청에 포함될 수 있습니다.

# 기본 제공되는 헤더값은 from corsheaders.defaults import default_methods 로 확인 가능합니다.
# 요청에 허용되는 HTTP Method 리스트입니다.
CORS_ALLOW_METHODS = [
   "GET",
   "OPTIONS",
]

# 기본 제공되는 헤더값은 from corshearder.defaults import default_headers 로 확인 가능합니다.
# 요청에 허용되는 HTTP Header 리스트입니다.
CORS_ALLOW_HEADERS = list(default_headers) + [	
   "custom-header-name",
]
반응형
SMALL

댓글