오늘은 CORS에 대해 정리를 해보자!
개인적인일과 준비로 오랜만에 포스팅을 한다!!
가장 보람되고 공부했을 때 여운이 많이 남는 게 바로 이 tow hours daily이다.
다시 또 달려보자
CORS! 언제 많이 겪었나 생각해보면 개인프로젝트를 할 때 많이 겪었다.
백엔드 API와 연결할 때 시뻘건 CORS 에러를 보면 내 눈도 시뻘게졌다.
그때는 뭔지 모르고 그저 access-control-allow-origin: *
를 넣어주곤했는데 이제 알고 쓸 수 있다!
자, CORS를 발생시키는자 누구인가
해당 API? 아니면 나의 웹 페이지?? 아니다 "브라우저"에서 차단을 시킨다.
왜 브라우저에서 차단을 시킬까?
생각해보자! 우리가 어떻게 API에 요청을 보내지?
보통 HTTP 요청을 보낸다. (HTTP 요청은 프로토콜 중 하나)
정리를 하면서 프로토콜에 대해 다시 한번 정리하고 싶어졌다. 프로토콜은 결국 컴퓨터와 컴퓨터 사이에 통신을 하는데 필요한 통신규약이다.
컴퓨터와 컴퓨터는 네트워크를 통해 통신을 한다. 이 네트워크망은 대표적으로 인터넷이있다! 인터넷 제공하는 업체 ISP(KT,SKT,LG)등의 인터넷망을 사용해서 우리는 다른 컴퓨터에게 데이터를 요청할 수 있다.
그럼 이렇게 HTTP 요청을 보내 서로 다른 컴퓨터에게 데이터를 요청할때 CORS 에러가 발생한다.
자, 기본적으로 브라우저는 다른 출처에서 오는 데이터 요청을 거부한다.
이를 SOR(Same Origin Resource)라고한다. 실은 다른 출처에서 오는 요청을 거부하는 애는 바로 이 SOR이다.
왜 그럼 다른 출처에서 오는 요청은 브라우저는 거부할까?
HTTP요청 등 프로토콜은 다른 컴퓨터와 내 컴퓨터와의 데이터 전송을 담당해준다.
이때 브라우저에는 cookie, 인증키, Token등의 정보를 저장하고있는데 만약 해당 API에서 내 cookie, 인증키, Token 의 정보를 빼갈 수 있지 않겠는가?
충분히 빼갈 수 있고 안심할 수 있는 사이트만 허용해주는게 좋다.
그렇기 때문에 "이 사이트 안심해? 그럼 나를 허용해" 라고 말하는게 CORS인 것이다.
CORS(Cross Origin Resource Sharing)
출처는 프로토콜, 도메인, 포트번호를 의미한다.
네이버는 다음 URL이 출처가 된다.
기본적으로 클라이언트(프론트엔드)에서 HTTP요청을 보낸다.
이때 header에 Origin에 출처가 담겨 서버에 전송된다.
사진 출처
like...this...
그럼 서버는 Access-Control-Allow-Origin에 허용 가능한 출처를 담아 클라이언트에게 다시 전달한다.
그럼 브라우저는 해당 Origin과 Access-Control-Allow-Origin을 비교한다. 이때 비교해서 같지 않다면 response를 버린다.(preflight request는 먼저 http요청을 보내지도 않는다.)
그럼 해결방법은?? Access-Control-Allow-Origin에 프론트서버를 추가해주면 된다!!
app.use(cors({ origin: "http://localhost:3000" }));
그래서 이런 cors 옵션을 사용해서 origin에 대한 정보를 서버에 저장한다.
또는 프록시 서버를 사용해서 데아터 중개소를 찾는것이다.
프록시서버=> 데이터 중개소
그럼 출처가 달라도 프록시서버가 믿고 가져와준다.
크게 3가지가 있다.
Simple request, Preflight request, Credentialed request
이 중 가장 많이 사용되는 시나리오인 Preflight request, Credentialed request를 살펴보겠다!
사실 브라우저는 요청을 보낼때 한번에 바로 보내지않고, 먼저 예비 요청을 보내 서버와 잘 통신되는지 확인한 후 본 요청을 보낸다.
여기서는 HTTP의 특별한 메소드인 OPTIONS가 사용된다.
이 OPTIONS는 클라이언트의 Origin과 서버의 Access-Control-Allow-Origin의 출처를 비교하는 역할을 한다.
여기서 비교한 출처가 다르면 CORS 에러를 보내고 같다면 원하는 데이터를 전송
이때 Access-Control-Allow-Origin:*이 사용가능
Preflight request와 메커니즘은 동일하지만 Cookie나 Session을 주고받는 http요청일 때 동작한다.
또 아주 중요한 정보를 담기떄문에
본 요청에서 Access-Control-Allow-Credentials: true 로 설정해주어야하고 Access-Control-Allow-Origin:*은 사용 불가능
이렇게 Cors에 대해 알아보았다.
정리하자면 다음과 같다.
CORS는 실제 다른 출처이기 때문에 발생시키는 에러가 아닌 나를 허용해주면 보여주지~ 라는 착한녀석
SOR가 오히려 동일 출처 정책으로 이 친구 때문에 다른 출처일때 오류가 발생한다.
결국 클라이언트와 서버사이에 데이터를 전송하면서 출처(프로토콜, 도메인, 포트번호)의 차이에 의해 발생하는 것이고 어떤 출처를 허용할 것이지를 옵션에 넣어주면 발생하지 않을 수 있다.