[Django] CORS

Hailey Park·2021년 11월 22일
0

Django

목록 보기
8/10
post-thumbnail

CORS

CORS는 Cross Origin Resource Sharing의 약자로, 도메인 또는 포트가 다른 서버의 자원을 요청하는 매커니즘이다.

최근 대부분의 웹 브라우저는 Javascript를 이용한 AJAX(Asynchronous Javascript XML)통신을 통한 데이터 송수신을 하는데, 다른 도메인을 가진 서버의 URL을 호출해 데이터를 가져오려고 하는 경우 보안 문제인 Cross Domain 이슈를 발생시켜 이를 차단한다.
(Javascript는 동일 출처 정책(Same Origin Policy)이 있다.) 그래서 데이터를 받을 수가 없다.

즉, 자신과 동일한 도메인에 한해서만 요청을 허용하고 처리해준다.

CORS 문제는 다른 도메인의 서버로부터 요청이 들어왔을 때, 헤더에 접근을 허락하는 내용이 없으면 발생한다.
예를 들어, 클라이언트는 localhost:3000이고 외부 서버는 localhost:8000이면 포트가 달라서 CORS가 발생할 수 있다. 이럴 경우, 외부 서버에서 보내는 요청의 헤더 (Access-Control-Allow-Origin response 헤더) cross origin HTTP 요청을 허가해 접근을 허락하는 내용을 추가해 주면 된다.

Cross Origin HTTP 요청을 허가해주는 방법

헤더에 접근을 허락하는 내용을 추가

1) pip install로 django-cors-headers 앱을 설치한다.

django-cors-headers는 Cross-Origin Resource Sharing(CORS)에 필요한 서버의 헤더를 조작하기 위한 앱이다.

django-cors-headers 장고앱을 이용해서 response에 CORS(Cross Origin Resource Sharing) 헤더를 추가한다,

이렇게 하면 다른 서버로부터 내 서버 앱으로 들어오는 브라우저를 통한 요청을 허가한다.

2) installed apps 목록에 corsheaders를 추가한다.

INSTALLED_APPS = [
    ...
    'corsheaders',
    ...
]
middleware class도 추가한다.
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware', 
    'django.middleware.common.CommonMiddleware', 
    ...
]

CorsMiddleware는 가능한 높게 위치시켜야 한다.

특히 Django의 CommonMiddleware나 Whitenoise의 WhiteNoiseMiddleware와 같은 응답을 생성할 수 있는 미들웨어 전이어야 한다.

이러한 미들웨어 전이 아닌 경우엔, 이러한 응답들에 CORS 헤더를 추가할 수 없기 때문이다.

3) Django settings에서 미들웨어의 동작을 구성해야 한다.
CORS_ORIGIN_WHITELIST에는 cross-site 요청을 허용하는 호스트들을 추가한다.

또는 모든 호스트를 허용하고 싶으면 CORS_ORIGIN_ALLOW_ALL을 True로 설정한다. 만약 CORS_ORIGIN_ALLOW_ALL이 True 이면, whitelist는 쓰이지 않고, 모든 origin에서의 요청이 허용된다.

Default는 False이다.

CORS_ORIGIN_WHITELIST는 cross-site HTTP 요청을 할 수 있는 권한이 주어지는 origin들의 리스트이다.

Default는 [ ] 이다.

Origin은 URI scheme + hostname + port 등으로 정의된다.

CORS_ORIGIN_ALLOW_ALL = True 
# <- 모든 호스트 허용

# or 

CORS_ORIGIN_WHITELIST = (
    "https://example.com",
    "https://sub.example.com",
    "http://localhost:8080",
    "http://127.0.0.1:9000"
)

이렇게 헤더에 추가해주면 된다.

Resource
https://oen-blog.tistory.com/46

profile
I'm a deeply superficial person.

0개의 댓글