CORS

김기현·2022년 2월 27일
2
post-thumbnail

Django로 API를 만들었는데 실습을 하다가 cors에러가 떴습니다. Cross Domain 이슈가 발생했는데, 이 문제가 왜 발생했을까요....?

CORS

CORSCross Origin Resource Sharing의 두문어로 도메인 또는 포트가 다른 서버의 자원을 요청하는 매커니즘입니다.

대부분의 웹 브라우저는 XML, JSON 등의 통신을 통한 데이터를 송수신하는데, 만약 다른 도메인을 가진 서버의 URL을 호출해 데이터를 가져오려고 하는 경우 Cross Domain 보안 이슈를 발생시킵니다.

이는 엔드포인트가 각각 다른 도메인을 가진 API를 구축하였는데, 우리가 아닌 다른 웹서비스에서 이 API에 접근해 마음대로 API를 호출해서 사용하면 안되기 때문입니다.

가벼운 예시로 https://velog.io/@tritny6516 도메인 내에서는 해당 도메인 내에 있는 URL을 호출해야지, 이 URL에서 https://github.com/의 URL은 AJAX, JSON으로 호출할 수 없습니다.

Same Origin Policy(동일 출처 정책)으로 도메인이 다른 서버로부터 요청을 받으면 보안 문제로 여겨 CORS 에러를 발생시켜 이를 차단합니다. 다시 말해서 해당 정책 때문에 브러우저에서 외부 서버가 cross-origin HTTP로 요청한 데이터를 보안 목적으로 차단합니다.

CORS 이슈 해결

CORS이슈는 다른 도메인의 서버로부터 요청이 들어왔을 때 header에 접근을 허락하는 내용이 없으면 발생하는 것으로 cross origin HTTP 요청을 허락해 접근을 허락하는 내용을 추가합니다.

요청 허가

  • 앱 설치

pip install django-cors-headers라는 앱을 설치합니다. 이는 Cross-Origin Resource Sharing에 필요한 서버의 헤더를 조작하기 위한 django 앱입니다.

  • installed apps에 추가
    미들웨워의 동작을 구성(가공)하기 위해 apps에 추가합니다.
INSTALLED_APPS = [
	 ...
    'corsheaders',
]
  • middleware class 추가
MIDDLEWARE = [
	...
    'corsheaders.middleware.CorsMiddleware',
    ...

]
  • middleware 동작 구성 추가
    CORS_ORIGIN_ALLOW_ALL = True 해당 동작은 모든 origin에서의 요청이 허용됩니다. 특정 도메인만 허용하고 싶다면 다음의 동작을 입력합니다.
CORS_ORIGIN_WHITELIST = (
    "https://handsomedavid.com",
    "http://localhost:8000",
    "http://127.0.0.1:8000"
)

Default는 False입니다.

CORS_ALLOW_CREDENTIALS = True 해당 동작은 쿠키가 cross-site HTTP 요청에 포함될 수 있다는 의미입니다.

Default는 False입니다.

  • CORS_ALLOW_METHODS
CORS_ALLOW_METHODS = (
    "DELETE",
    "GET",
    "OPTIONS",
    "PATCH",
    "POST",
    "PUT",
)

커스텀 메소드들은 확장해서 사용하면 됩니다.

-CORS_ALLOW_HEADERS
실제 요청을 할 때 사용할 수 있는 non-standard HTTP 헤더 목록입니다.

CORS_ALLOW_HEADERS = (
    "accept",
    "accept-encoding",
    "authorization",
    "content-type",
    "dnt",
    "origin",
    "user-agent",
    "x-csrftoken",
    "x-requested-with",
)

커스텀 헤더들 또한 확장해서 사용하면 됩니다.

보안 사항들

CORS_ALLOW_HEADERS의 동작사항인 x-csrftoken은 CSRF의 “교차 사이트” 부분으로의 공격을 막기 위한 용도입니다. 해당 블로그에 정리해두었습니다.

x-requested-with 헤더는, 해당 요청이 Ajax라는 걸 의미합니다. 표준 헤더는 아닌 커스텀 헤더이며, jQuery와 Prototype을 포함한 대부분의 자바스크립트 라이브러리에서 Ajax 요청을 보낼 때에 이 헤더를 설정합니다.

profile
피자, 코드, 커피를 사랑하는 피코커

2개의 댓글

comment-user-thumbnail
2022년 2월 27일

미들웨어 체크

1개의 답글