CORS

jeong_hyeon·2022년 4월 2일
0
post-thumbnail

CORS

CORS = Cross- Origin Resource Sharing

: 교차 출처 리소스 공유 = 다른출처 리소스 공유

:도메인 또는 포트가 다른서버의 자원을 요청하는 매커니즘

출처란? (Origin)

서버의 위치를 찾아가기 위해 필요한 가장 기본적인 것들을 합쳐 놓은 것


Protocol + ... + Port 까지 전부 합친것을 Origin이라고 부른다.

출처 내의 포트번호는 생략이 가능

why?

Http, Https 프로토콜의 기본 포트 번호가 정해져 있기때문

포트번호를 작성하는경우 포트번호까지 모두 일치해야 같은 출처로 인정이 된다.

하지만 이러한 케이스의 명확한 정의가 표준으로 정해진것이 아니기 때문에 케바케 가 될수있다.

(정확히 이야기하면 같은 상황인데 어떤경우에는 같은출처 또다른 경우에는 다른출처로 판단될수있다.)

우리는 브라우저의 개발자 도구의 콘솔에서 Location 객체가 가지고 있는 origin
프로퍼티에 접근함으로써 손 쉽게 어플리케이션이 실행되고 있는 출처를 알아낼 수도 있다.

SOP(Same-Origin-Policy)

웹에서는 다른출처로의 리소스 요청을 제한하는것과 관련된 두가지 정책이 있고 CORS와 SOP가 있다.

SOP는 2011년에 등장한 보안정책으로 “같은 출처에서만 리소스를 공유할수 있다.”라는 규칙을 가진 정책이다.


최종정리

다른 도메인이 가진 서버의 URL을 호출해 데이터를 자져오려는경우 Corss Domain이슈를 발생시킴

이유

우리 웹서비스에서 사용하기위해 다른 서브도메인을 가진 API서버를 구축했는데 우리가 아닌 다른 웹서비스에서 이 API 서버에 접근해서 마음대로 API를 호출해서 사용하면 안되기 때문

예를들어

www.jeonghyeon.co.kr 이라는 도메인에서는 www.jeonghyeon.co.kr 도메인 내에 있는 URL만을 호출할수 있다.

www.jeonghyeon.co.kr 도메인에서 www.velog.com 도메인의 URL은 AJAX(JS를 이용한 통신)로 호출할수없다.

Javascript는 동일 출처 정책이라는 정책을 두어 도메인이 다른 서버로부터 요청을 받으면 보안 문제로 간주하고 CORS 이슈를 발생시켜 이를 차단한다.

동일 출처 정책(Same Origin Policy) 때문에 CORS가 발생하는데, 브라우저에서 외부 서버가 cross-origin HTTP로 요청한 데이터를 보안 목적으로 차단한다. 그래서 데이터를 받을 수가 없다.

결론

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

문제해결방법

CORS문제 = 다른 도메인에서 서버로 요청이 들어왔을경우 헤더에 접근을 허락하는 내용이 없어서 발생

(가장 쉬운 해결방법은 클라이언트와 서버가 같은 도메인과 포트를 사용하는 거지만.. )

방법 = 외부 서버에서 보내는 요청의 헤더(Access-Control-Allow-Origin response 헤더)에 cross origin HTTP 요청을 허가해 접근을 허락하는 내용을 추가해 주면 된다.

django-cors-headers

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

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

pip install django-cors-headers

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

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

  1. installed apps 목록에 corsheaders를 추가
INSTALLED_APPS = [
...
'corsheaders',
...
]
  1. middleware class도 추가
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware', # <- 가능한 높게 위치시켜야 한다.
    'django.middleware.common.CommonMiddleware', 
    ...
]

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

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

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

:파이썬은 위에서 아래로 읽기때문

  1. Django settings에서 미들웨어의 동작을 구성해야 한다.
##CORS
CORS_ORIGIN_ALLOW_ALL=True # <- 모든 호스트 허용
CORS_ALLOW_CREDENTIALS = True # <-쿠키가 cross-site HTTP 요청에 포함될 수 있다

CORS_ALLOW_METHODS = (  #<-실제 요청에 허용되는 HTTP 동사 리스트
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
)

CORS_ALLOW_HEADERS = ( <-실제 요청을 할 때 사용될 수 있는 non-standard HTTP 헤더 목록// 현재 기본값
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
)

APPEND_SLASH = False #<- / 관련 에러 제거

APPEND_SLASH는 자동으로 URL 끝에 슬래시('/')를 붙여 주는 django의 옵션으로 default값은 True이다.

브라우저에서 요청한 URL이 urls.py 파일 안에

정의된 패턴과 일치하는 것이 없을 때만 자동으로 붙여서

다시 한번 일치하는 것이 있나 검사한다.

settings.py에서 APPEND_SLASH = False를 해주면 슬래시를 붙여주는 위치를 자유롭게 설계가능 하다.


URL과 도메인의 차이

1) URLURL은 도메인을 포함하는 경로이다. 특정 웹사이트의 특정 위치까지 가기위한 전체 경로라고 보면 된다출처: https://na27.tistory.com/149 [na27]예를 들어 TEST 폴더 안의 TEST.PDF라는 파일은 http://도메인/test/test.pdf/ 가 URL이다.

2) 도메인도메인은 예를 들어 http://www.naver.com 에서 www.naver.com이 도메인이다.

  • DNS(Domain Name System) 서버사용자가 웹사이트에 접속할 때 도메인 이름(www.naver.com)접속하면, DNS 서버에 도메인 이름이 보내진다. 그럼 DNS 서버는 그 도메인 이름에 연결된 아이피 주소(ex. 202.179.177.22 2017년 9월 17일 기준 네이버 웹사이트 IP 주소) 응답을 사용자 컴퓨터에 보낸다. 그럼 사용자는 응답받은 아이피 주소로 실제 데이터 처리를 하는 서버에 다시 데이터 요청을 하고 데이터를 응답 받게 된다.

0개의 댓글