ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 웹 개발자라면 알아야 할 "CORS"에 대해서!
    Web 2021. 7. 5. 19:32
    반응형

    얼마 전 좋은 기회를 해볼 수 있었다.

    바로 신입 프론트엔드 개발자 면접 자리였다.

    항상 면접자로서만 준비를 해봤지 면접관으로서의 생각은 못해봤는데 이렇게 경험을 해볼 수 있어서 좋았다.

    물론 내 처지에 누가 누구한테 질문을 하겠냐만은... 기술면접은 시니어분에게 맡기고 나는 주로 평소 공부 방법, 학습을 즐기는지, 계속 공부를 해나가야하는데 부담스럽지 않은지 등에 대한 질문을 했다.

     

    ( 주변에서 회사에 들어갔다고 안도감에 공부를 놔버리는 경우를 봤기 때문이다...ㅠ_ㅠ )

     

    어차피 신입 개발자를 뽑는 자리이기 때문에 어렵지 않은 질문들을 했다.

    그 중에서도 대답을 곧 잘 하는 사람들의 경우 조금 더 깊은 질문을 하기도 했는데, 그 정도가 바로 CORS 였다.

    그런데 CORS를 겪어도 보았고, 블로그에 정리도 했으면서 잘 모르는 사람도 있었다...

    그래서 이번에는 CORS에 대한 정리를 해놓으려고 한다.

     


    CORS는 Cross Origin Resource Sharing의 약자인데, 백엔드와 통신을 해본 경우 알 수 있겠지만 프론트단에서 API로 정보를 받아오기 위해서 HTTP 요청을 보냈을 때, 갑자기 콘솔 창에  빨간색으로 에러창을 뜨는 것을 본적있을 것이다.

    이는 어떤 사이트에서 주소가 서로 다른 서버로 요청을 보낼 때 접하게 될 수 있다.

     

    나도 처음 이를 접했을 때는 당연히 내 잘 못 인줄 알고 한참을 헤매었던 기억이 있다.

    왜냐하면 postman과 같은 곳에서 찍어보면 정상적으로 나오기 때문이다.

    그래서 내 GET 요청이 잘 못 되었나 했는데... 찾아보다가 백엔드 하시는 분에게 물어보니 백엔드 실수라고 하더라.... ㅠ

     

    CORS에 대해서 간단하게 설명해보자면, 우리가 사용하고 있는 브라우저(크롬, 사파리 등)가 내가 방문한, 혹은 개발하고 있는 어떤 사이트를 믿지 못해서 request를 하지 못하도록 브라우저 쪽에서 막고 있는 것이다.

     

    CORS에 대해서 깊게 알아보기 전에 알아보면 좋을 것이 있다 바로, 애초에 브라우저에서는 서로 출처가 다른 곳에서 요청을 주고 받는 것이 되지 않는 것이 기본값이다 라는 것이다.

    그런데 웹 생태계가 다양해지면서 여러 서비스들간에 보다 자유롭게 데이터를 주고 받을 필요성이 생겼는데, 브라우저에서는 여전히 이를 막고 있으니까 개발자들은 우회하는 방향으로 이를 해결해나갔다.

    그래서 이를 합의 된 출처들간에는 합법적으로 허용해주기 위해서 어떠한 기준을 충족 시키게 되면 Resource sharing이 되도록 만들어진 것이 바로 CORS 즉, 교차 출처 자원 공유 방식 인 것이다.

     


     

    우리가 "A사이트"에 개인정보를 조회하는 요청을 할 때 브라우저에 저장 된 "A사이트"의 토큰을 실어서 "A사이트"로 보내는데 이 때 정보를 탈취하여 다른 서버로 보내버릴 수 있다. 이런 식으로 개인정보가 해킹 될 수 있는 것이다.

    브라우저는 이런 일이 벌어지기 전에 다른 사이트로 요청이 가지 못하도록 막는 일을 하는데 이를 SOP (Same-Origin Policy) 라고 한다.

    직역하자면 "같은 출처 정책"인데 같은 출처의 URL끼리만 API 등의 접근이 가능하도록 하는 것이다.

    그리고 CORS의 경우 요청을 막고 있는 SOP를 풀어주는 역할을 하는 것이다.

     

    앞서 말한 것 처럼 CORS는 Cross origin Resource Sharing, SOP는 Same origin policy로써 서로 반대되는 개념을 가지고 있는데, CORS의 경우 서로 다른 출처(Cross origin)간의 resource를 sharing 할 수 있도록 하는 것을 말한다.

     

    출처, 리소스 등 말이 어렵다고 느껴질 수 있는데, 출처는 보내고 받는 각각의 위치 즉, Web Site, API 주소를 말하며, 리소스는 주고 받는 데이터를 생각하면 된다.

    즉, A 사이트와 연결 된 다른 사이트가 정보요청, 반환 등이 가능하도록 만들어주는 것이 CORS라는 것이다. 

    CORS error message가 뜨게 되는 경우 "이 사이트에 가고 싶다면 CORS를 허용해줘라" 라고 말하는 것이라고 할 수 있다.

     


     

    그렇다면 앞서 "어떤 기준을 충족시키게 되면" 이라고 했는데, 그 기준이 무엇일까?

    아주 간단하다! 요청을 받는 백엔드 쪽에서 이걸 허락 할 다른 출처들을 미리 명시해두면 되는 것이다.

    백엔드 프레임워크를 잘 살펴보면 CORS 옵션을 넣는 방법들이 쉽게 마련되어있으니 이를 확인해 보면 도움이 될 것이다.

    나의 경우 이런 이유로 이와 같은 상황에서 "백엔드 실수에요.." 라는 이야기를 들을 수 있었던 것이다.

     


    자! 조금 더 깊이 들어가보자!

    만약 "A 사이트"에서 Kakao API에 요청을 보낸다고 해보자.

    브라우저는 이렇게 A 사이트와 Kakao라는 서로 다른 출처에 요청을 보낼 때는 Origin이라는 header를 추가하게 된다.

    ( 이 header는 데이터의 맨 앞쪽에 붙은 보충 정보라고 볼 수 있다. 받는 쪽의 IP주소, 사용할 프로토콜, 옵션 등이 담기는데 우편으로 예를 들면 봉투에 적힌 내용이라고 볼 수 있을 것이다 )

    브라우저의 상황에서 header 안에는 요청하는 쪽의 scheme과 domain, PORT가 담긴다.

    ( scheme(스킴)이란 http, ftp, telnet 등 요청 할 자원에 접근 할 방법( = 프로토콜)을 말하는 것이다 )

     

    우리가 흔히 dev server를 열면 localhost:3000 번이 뜨는 것을 볼 수 있을 것이다.

    정확하게는 https://localhost:3000 인데 이 부분에서 https가 scheme이 되는 것이고, localhost가 domain 부분( 도메인이라고 말하기 조금 애매하지만...), 그리고 뒤에 3000부분에 PORT 인 것이다.

     

    요청을 받은 Kakao API 서버는 요청에 대한 응답의 header에 지정된 Access-Control-Allow-Origin 정보를 실어서 보내게 된다.

    이 후 브라우저가 둘을 비교해서 Origin에서 보낸 출처 값이 서버의 답장 header에 담긴 Access-Control-Allow-Origin에 똑같이 있으면 안전한 요청으로 생각하여 응답 데이터를 받아오게 되는 것이다.

     

    단순한 정보 요청이라면 조금 간편하겠지만, Token 등 사용자 식별 정보가 담긴 요청에 대해서는 조금 더 엄격하다.

    보내는 측에서는 요청의 옵션에 credentials 항목을 true로 셋팅해놔야하고, 받는 쪽에서도 와일드카드( * )를 사용하는 것이 아니라 보내는 쪽의 웹페이지 주소를 정확하게 명시한 다음 Access-Control-Allow-Credentials 항목을 true로 만들어줘야한다.

     

    CORS에서 요청은 크게 Simple Request, Preflight Request로 구분 될 수 있다.

    위와 같은 방식을 Simple Request라고 하는데 GET / PUT 등의 일정 조건의 요청들에 사용 되는 방식이며,

    POST / DELETE 등의 경우 본 요청을 보내기 전에 Preflight Request라는 것을 먼저 보내서 본 요청이 안전한지 확인하고, 거기서 허락이 떨어져야 본격적으로 요청을 보낼 수 있다.

     

    즉, Simple Request의 경우 요청을 다 보내지만 통과를 못하면 그에 대한 답만 받아오지 못하는 것이고, Preflight Request의 경우 요청에 의해서 서버 데이터가 변경 될 수 있으므로 요청을 보내는 것부터 우선 허락을 받아야한다.

    ( 물론 Simple Request에서도 서버 데이터가 변경 되는 경우가 있으므로 백엔드를 짤 때 보안에 대한 것을 충분히 고려하여 작성해야한다  )

     

     

     

     

     

    Ref : https://www.youtube.com/watch?v=bW31xiNB8Nc

    반응형
Designed by Tistory.