http://localhost:80/user/login
위와 같은 URL이 있다고 할 때, http://
를 프로토콜, localhost
를 host, :80
을 port 라고 한다.
URL의 프로토콜, host, port 이 세 가지가 모두 동일한 URL에 대해서 같은 출처다
라고 표현을 한다.
SOP란
다른 출처
리소스를 사용하는 것을 제한하는 보안 방식이다.
위 출처에 대한 설명을 참고해서 다음 상황을 생각해보자.
인스타그램 사용자가 인증 토큰을 받아 인스타그램을 사용하고 있다. 해커가 사용자에게 링크를 보냈는데 이를 클릭하면 http://hacker.hk 사이트로 이동이 되고, 해커가 작성해둔 게시글이 작성된다.
위와 같은 상황에서 인스타그램은 http://hacker.hk
라는 출처가 사용자의 출처와 다른 출처이므로 이를 허용하지 않는다는 것이다.
그런데 다른 출처와 리소스를 공유하고 싶을 때는 어떻게 하지?
이런 경우 사용하는 것이 CORS(Cross-Origin Resource Sharing
) 기술이다.
CORS의 정의는 다음과 같이 나와 있다.
추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처
의 선택 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는
체제이다.
크게 3가지 요청 방식이 존재한다.
첫번째는 Preflight
요청이다. OPTIONS
메서드를 통해 다른 도메인의 리소스 요청이 가능한지 서버에 미리 물어보는 요청을 보내고 괜찮다는 응답을 받아 확인이 되면 그 때 실제 요청을 보내는 방법이다.
만약 Preflight
요청을 하지 않고 서버에 직접 요청을 보낸다면, CORS를 모르는 서버는 모든 작업을 완료한 뒤 응답을 보내고 브라우저는 뒤늦게
CORS 오류를 띄울 것이다. 그러나 이미 모든 상황은 일어났고, 늦었다. 이러한 이유로 사전 요청을 보낸다고 이해하면 좋다.
두번째는 Simple
요청이다.
GET, POST, HEAD
메서드에 대해서 application/x-www-form-urlencoded, multipart/form-data, text/plain
컨텐트 타입을 만족하며 Accept, Accept-Language, Content-Language, Content-Type
만을 허용하는 헤더의 요청을 보낼 때 사전 요청 없이 바로 요청을 보내는 방식이다.
서버는 Access-Control-Allow-Origin
헤더 값을 확인하여 요청의 Origin 출처
와 비교하여 요청 처리를 판단한다.
마지막 세번째는 Credentials
요청으로, 인증 관련 헤더(credentials: include
)를 포함해서 보내는 요청이다.
서버측은 Access-Control-Allow-Credentials: true
값으로 요청 값과 비교하여 판단한다.
영상 출처: [10분 테코톡] 🌳 나봄의 CORS