TIL - CORS

케이·2022년 5월 11일
0

TIL

목록 보기
13/13

아래의 글은 개인 학습을 위해 공식문서와 블로그 등을 정리한 것입니다. 혹시 잘못된 부분이 있어 지적해주신다면 감사하겠습니다🙏🏻

CORS를 알게 된 계기

FE분들과 프로젝트를 진행하다 마주쳤다. 발표를 2시간도 남기지 않은 상태에서 처음보는 403에러와 경고때문에 많이 당황했었다. 다행히 주변분들에게 물어물어 CORS때문에 생기는 이슈임을 알게되어 코드 수정을 할 수 있었다. 하지만.. 발표 10분을 앞두고 또 터진 CORS에러... 왜 터졌을지는 아래에서 설명하겠다..

CORS란?

Cross-Origin Resource Sharing의 줄임말.
CORS를 이해하기 위해선 SOP(Same-Origin Policy)도 알아두면 좋은데..
결국 이 둘이 무엇이냐 하면..
웹이라는 공간에서 다른 곳에 있는 리소스를 가져와서 사용하는 일은 굉장히 흔한일이다. SOP는 말 그대로 '같은 출처에서만 리소스를 공유할 수 있다'라는 규칙을 가진 정책이고 이 때문에 리소스 출처가 다르더라도 사용하는 것이 해당 정책에 위반되는 것이었다. 하지만 위에서 언급했던 것처럼 웹에서 다른 곳의 리소스를 사용하는 일은 흔한 일이라 몇 가지 예외 조항을 두고 리소스 출처가 다르더라도 허용하기로 했는데 그 중 하나가 CORS 정책을 지킨 리소스 요청이다.

(출처: https://developer.mozilla.org/ko/docs/Web/HTTP/CORS)

여기서 중요한 것은 출처를 비교하고 판단하는 것은 브라우저다. (브라우저에 로직이 구현되어 있다고 보는게 맞겠지..)
만약 CORS 정책을 위반하는 리소스 요청을 하더라도 서버는 정상적으로 응답을 한다.
하지만 브라우저가 CORS 정책 위반이라고 판단하면 그 응답을 버려버린다.

단순 요청(Simple Request)

단순 요청은 프리플라이트(미리전송)을 하지 않고 서버에게 바로 요청을 한뒤 서버가 이에 대한 응답 헤더에
Access-Control-Allow-Origin를 포함하면 브라우저가 CORS 정책 위반 여부를 검사하는 방식이다.
예를 들어 Access-Control-Allow-Origin=* 이라고 응답이 온다면 모든 도메인에서 접근할 수 있음을 의미한다. 특정한 곳에서의 요청만 접근을 허용하고 싶은 경우에는 Access-Control-Allow-Origin = 주소를 적어주면 된다.

단순요청은 다음 조건들을 모두 충족하는 요청이어야 하는데
1. 요청 메서드는 GET, HEAD, POST 중 하나여야 한다.
2. 유저 에이전트가 자동으로 설정 한 헤더 외에 Accept, Accept-Language, Content-Language, Content-Type (Fetch 명세에서 “CORS-safelisted request-header”로 정의한 헤더)를 제외한 헤더를 사용하면 안된다.
3. Content-Type을 사용하는 경우에는 application/x-www-form-urlencoded, multipart/form-data, text/plain만 허용된다.

프리플라이트(Preflight)

CORS 명세는 브라우저가 OPTIONS 메서드에서 프리플라이트를 지원하는 메서드를 요청하고 서버의 허락이 떨어지면 실제 요청을 보내도록 요구한다.
-> OPTIONS 메서드를 통해 다른 도메인의 리소스로 HTTP 요청을 보내 실제 요청이 전송하기에 안전한지 확인한다. (미리 전송)

(출처: https://developer.mozilla.org/ko/docs/Web/HTTP/CORS)

그래서.. 대충 알겠고..
어떻게 해결하는건데? 라고 물어본다면..

CORS 해결 방법

헤더의 Access-Control-Allow-Origin에 맞는 값을 세팅 해주면 된다.

정말 끝인가보다 했는데...
allwedOrigins에 값을 세팅했지만 여전히 에러를 뿜어내는 브라우저.
allowedMethods를 지정해주지 않아서였다.. (발표 5분전에 다행히 해당 내용을 찾아 추가해주었고 문제 해결!)

아래의 코드는 CORS 관련 추가해준 코드이다. 원래는 이것보다 훨씬 간단했는데 config 파일을 분리한다고 저렇게 만들어 둔 뒤에 실제로 확인해보진 못했다. (프로젝트가 끝나서 라는 핑계를 대본다..)

이후 프로젝트에서는 아래와 같이 작성하고 서버에 띄워 사용했더니 문제 없이 사용할 수 있었다.

마치며

역시 삽질이 아니면, 내가 직접 마주쳐본 것이 아니면 제대로 기억하기 어렵다. 반대로 삽질 + 경험은 항상 무엇인가를 남기는 것 같다. CORS도 정말 찍먹 정도로만 살펴보았는데 좋은 개발자가 되기 위해 나중에라도 더 공부해야 하지 않을까? 라는 생각이 든다.

참고

https://developer.mozilla.org/ko/docs/Web/HTTP/CORS
https://evan-moon.github.io/2020/05/21/about-cors/
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=good_ray&logNo=221547039408
https://wonit.tistory.com/572

profile
삽질하며 깨닫고 배웁니다. (a.k.a 프로삽질러) + 이 구역의 회고왕

0개의 댓글