CORS

HunkiKim·2022년 9월 16일
0

먼저 용어정리.

  • SOP (Same Origin Policy) : 다른 출처의 리소스를 사용하는 것에 제한 하는 보안 방식
    • 그럼 출처란 무엇일까? Protocol, Host , Port , Path , Query String, Fragment 등 URI에만 해도 많은 것들이 들어있다.
    • 여기서 Protocol, Host, Port를 통해 같은 출처인지 다른 출처인지 판단이 가능하다. 무엇이라도 하나가 다르면 다른 출처라고 판단하게 된다.
    • 브라우저는 hots를 string value를 통해 비교를 하게 된다. 따라서 127.0.0.1과 localhost는 다르다.
    • 또한 host 뒤쪽의 resource나 identifier, query string, fragment등은 비교하지 않는다.
  • SOP를 쓰는 이유
    • 이메일 같은 곳에 흥미로운 주소를 담아 보내게 하고 주소를 누르면 특정한 사이트에게 명령을 내릴 수 있다.
    • 하지만 SOP를 사용하면 원래 자신의 사이트와 출처가 다르기 때문에 Cross Origin이 발생해 이를 막는다.
  • 그러면 다른 출처의 리소스가 필요하면 ?
    • CORS

CORS (Cross-Origin Resource Sharing)

CORS란 말 그대로 다른 출처의 자원을 공유하는 것이다.

CORS 접근 제어

  • Simple Request
    • Preflight와 달리 요청없이 바로 요청을날린다.
    • 대신 아래 조건 만족해야 한다.
      • GET, POST, HEAD 메서드 중 하나
      • Content-Type
        • A. application/x-www-form-urlencoded
        • multipart/form-data
        • text/plain
      • 헤더는 Accept, Accept-Language, Content-Language, Content-Type 만 허용한다.
  • Preflight Request
    • OPTIONS 메서드를 통해 다른 도메인의 리소스에 요청이 가능한지 확인하는 작업이다.
    • 즉 서버에게 요청 보내도 되는지 확인한다.
    • 요청이 가능하면 그 때 실제 요청을 보내게 된다.
    • 즉 PR(Preflight Request)를 보내고 응답을 받 뒤 다시 실제 요청을 보내서 실제 응답을 받는 원리이다.
    • 이에 맞는 포맷이 있다.
    • 아래는 PREFLIGHT REQUEST에 대한 예시이다.
      • Origin : 요청 출처
      • Access-Control-Request-Method : 실제 요청의 메서드
      • Access-Control-Request-Headers : 실제 요청의 추가 헤더 (실제로 보내는 추가 헤더들)
OPTIONS /doc HTTP/1.1
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PING... 
  • 아래는 PREFLIGHT RESPONSE에 대한 예시이다.
    • Acceess-Control-Allow-Origin: 서버 측 허가 출처
    • Access-Control-Allow-Method : 서버 측 허가 메서드
    • Access-Control-Allow-Headers : 서버 측 허가 헤더
    • Access-Control-Max-Age : Preflight 응답 캐시 기간
Acceess-Control-Allow-Origin: http://foo.example
- Access-Control-Allow-Method : POST, GET, OPTIONS
- Access-Control-Allow-Headers : X-PINGO..
- Access-Control-Max-Age : 88888
  • 딱봐도 리소스적으로 좋지가 않다.
    • 두 번 이나 왕복해야함
    • 이를 캐시를 두며 살짝 해결함
    • 응답 코드는 200대, 응답 바디는 비어있는게 좋다.
  • 왜 굳이 Preflight?
    • CORS를 모르는 서버를 위해
    • CORS설정이 없는 상태로 서버를 요청을 하면 이미 서버가 처리를 다 처리를 했기 때문에 리소스적으로 개손해 + DB도 이미 처리가 끝남
    • 그래서 Preflight로 처리를 하면 이런 일이 생길걱정 없음
  • Credentialed Request
    • 인증 관련 헤더를 포함할 때 사용하는 요청이다.
      • Cookie, JWT Token 등을 자동으로 담아서 보내고 싶을때 credentials : include를 하면 된다.
      • 서버도 Access-Control-Allow-Credentials :true로 설정해야 한다. (이건 Origin을 *로 허용하지 않는다.)

해결법

  1. 프론트 프록시 서버 설정 바꾸기 (개발 환경)
    • 브라우저에선 Same Origin형식으로 프론트에 요청
    • 따라서 브라우저에선 터지진 않는다.
  2. 직접 헤더에 설정하기
    • 이 방법은 쉽지않다.
  3. 스프링 부트 이용하기
    • 최고의 방법이다.
    • 그냥 어노테이션 붙여서 쓰거나 Config에서 해결이 가능하다.

0개의 댓글