ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CORS
    CS 2022. 5. 31. 18:43
    728x90

    CORS(Cross Origin Resource Sharing)

    웹 프론트 엔드와 api 서버를 따로 구성하는 경우, 프론트 엔드에서 다른 origin의  api 서버로 요청을 보내면 문제가 발생한다. 이 문제를 CORS라고 한다.

    쉽게 말해서 CORS정책은 우리가 가져오는 리소스가 안전한지 검사하는 관문이다.

    여기서 말하는 Origin 이란, 아래의 세 가지 요소를 조합한 것을 말한다.

    URL의 Protocol, Host, Port를 통해 같은 출처인지 판단할 수 있다.

    배경

    SOP 정책 : 같은 출처에서만 리소스를 공유할 수 있다.

    예전에는 브라우저에서 요청을 보내면, 서버는 해당하는 로직을 수행한 뒤 HTML 페이지를 렌더링 한 뒤 브라우저에 반환해주는 방식이 일반적이었다. 즉, 하나의 서버(동일한 Origin)에서 모든 작업이 수행되었다.

    그렇기 때문에 웹 사이트에서 다른 서버로 요청을 보낸다는 것을 무언가 보안상 악의적인 행동을 하려는 것으로 생각했다. 그래서 브라우저에서는 같은 Origin이 아니라면 요청을 막아버리는 선택을 했던 것이고, 이것이 SOP 정책이다. 하지만 점점 웹 사이트에서 하는 일이 많아지면서 이러한 정책이 불편해지기 시작했고, 그에 따라 이러한 SOP 를 우회하기 위한 방법들이 나오기 시작했다. 그 방법들 중 하나가 JSONP 라는 방법인데, HTML의 <script> 태그의 경우에는 다른 Origin 의 파일을 불러오는 것이 가능했고 이 것을 리소스 요청을 주고받는데 우회적으로 사용한 것이었다. 스크립트를 불러오는 것처럼 사용을 하지만 실제로는 서버에서 데이터를 반환하는 용도로 사용을 했다.

     

    CORS 정책

    이러한 방식의 우회를 계속 두고 볼 수 없지만, 너무 수요가 많았기 때문에 공식적으로 특정한 제약조건 속에서 cross-origin 요청을 허용하도록 나온 정책이 CORS 이다. SOP와 CORS에 대해 더 자세히 알아보겠다.

     

    SOP란?

    다른 출처의 리소스를 사용하는 것에 제한하는 보안 방식

    Origin이 동일한지 확인하는 방법으로 체크합니다.

    그렇다면 다른 출처의 리소스가 필요한 경우엔 어떻게 해야할까?

     

    CORS(Cross-Origin Resource Sharing)

    교차 출처 리소스 공유란 뜻으로, 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다.

    CORS 동작 방식에는 세 가지 시나리오가 존재한다.

    • Simple Request (단순 요청)
    • Preflight Request (사전 요청)
    • Credentialed Request (인증 정보를 포함한 요청)

    CORS 접근 제어 시나리오

    - Preflight Request(사전 요청 - 사전 확인 작업)

    ex) 오늘 너네집 놀러가도돼? 대답에 따라 놀러갈지 가지 않을지 정한다!

    1. OPTIONS 메서드를 통해 다른 도메인의 리소스에 요청이 가능한지 확인

    2. 요청이 가능한다면 실제 요청(Actual Request)을 보낸다.

    preflight의 format

    Origin : 어디서 날라가는 거야

    Access-Control-Requet-Methods : 이 요청의 메서드를 보낼거야!

    Access-Control-Requet-Headers : 실제 요청 추가 헤더가 뭐뭐 가능할까?

    Access-Control-Allow-Origin : 이 Origin은 허가된 Origin이야

    Access-Control-Allow-Methods : 이렇 메서드들 허가 됐어

    Access-Control-Allow-Headers : 이 헤더들은 허가 됐어

    Access-Control-Max-Age : 응답 캐시가 유효한 시간

    * Acess-Control-Max-Age : perflight는 예비 요청, 본 요청 총 두번의 요청을 보내는데 이게 리소스적으로 좋지 않기 때문에 브라우저는 preflight 응답에 대해 캐싱을 해두고 다음에 같은 요청이오면 사전 요청을 미리 보내지 않고 본 요청으로 넘어갈 수 있다.

    특징)

    - 응답 코드는 200대여야 함.

    - 응답 바디는 비어있는 것이 좋다.

     

    - Simple Request

    Preflight 요청 없이 바로 CORS인지 확인한다.

    다음 조건을 만족해야만 가능하다.

    1) GET, POST, HEAD 메서드

    2) Content-Type

      a)  application/x-www-form-urlencoded

      b) multipart/form-data
      c) text/plain

    3) 헤더는 다음 4개만 허용된다.

      a) Accept
      b) Accept-Language
      c) Content-Language
      d) Content-Type

    client는 나는 Origin: foo.example인데 이런 요청 보낼게 > Server는 ok 모든 origin을 허가 할게 (Access-Control-Allow-Origin이 *이기 때문)

     

    - Credentialed Request

    인증 관련 헤더를 포함할 때 사용하는 요청

    쿠키나 JWT 토큰을 클라이언트에서 자동으로 담아서 보내고 싶을 때

    1. 요청 메시지에 다음과 같이 작성한다.

    Access-Control-Allow-Credentials : include

    2. 서버도 위의 헤더를 받기 위한 옵션을 작성

    Access-Control-Allow-Credentials : true

    Access-Control-Allow-Origin : *  > 불가능하다. 반드시 정확한 출처를 기입해줘야한다.

     

    참조 : https://kyu9341.github.io/WEB/2020/10/24/WEB_CORS/

    https://webcache.googleusercontent.com/search?q=cache:pG2Iq1qtF1MJ:https://inpa.tistory.com/entry/WEB-%25F0%259F%2593%259A-CORS-%25F0%259F%2592%25AF-%25EC%25A0%2595%25EB%25A6%25AC-%25ED%2595%25B4%25EA%25B2%25B0-%25EB%25B0%25A9%25EB%25B2%2595-%25F0%259F%2591%258F+&cd=3&hl=ko&ct=clnk&gl=kr 

    https://www.youtube.com/watch?v=-2TgkKYmJt4

    728x90

    댓글

Designed by Tistory.