감상문

CORS

ihl 2021. 10. 11. 00:26

  CORS 오류는 백엔드와 프론트엔드를 연동하려할 때 흔하게 볼 수 있는 오류이다. 이 오류가 왜 발생하는지, 어떻게 해결할 수 있는지 알아보자.

 

  • SOP(Same Origin Policy) : 다른 출처의 리소스를 사용하는 것에 제한을 두는 보안 방식
    • Protocol-Host-Port가 같다면 같은 출처이다.
      • IE는 Port가 달라도 같은 출처로 취급한다.
      • Host는 String Value로 비교된다.
        • http://localhost !== http://127.0.0.1 다른 출처
        • http://localhost/api/cors === http://localhost 동일 출처
    • SOP를 쓰는 이유
      • 자신의 출처와 다른 곳에서 온 요청이 오면 안전한 요청인지 장담할 수 없기 때문에 
  • CORS(Cross Origin Resource Saring) : 추가 HTTP 헤더를 사용하여 한 출처에서 실행중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제
    • CORS 접근제어 시나리오
      • Preflight Request : Options 메서드를 통해 다른 도메인의 리소스에 요청이 가능한지 확인
        • 본 요청을 보내기 전에 요청을 보내도 되는지 Options 메서드를 통해 사전 확인 작업
        • 요청이 가능하다는 응답을 받은 후에 실제 요청을 보낸다.
        • Preflight 요청 Header Format
          • Origin: 요청 출처
          • Access-Control-Request-Method: 실제 요청의 메서드
          • Access-Control-Request-Headers: 실제 요청의 추가 헤더
        • Preflight 응답 Header Format
          • Access-Control-Allow-Origin: 서버 측 허가 출처
          • Access-Control-Allow-Methods: 서버 측 허가 메서드
          • Access-Control-Allow-Headers: 서버 측 허가 헤더
          • Access-Control-Max-Age: Preflight 응답 캐시 기간
            • Preflight 요청에 대해 브라우저에서 캐싱해두고, 다음에 같은 곳으로 요청을 보낼 때 Preflight요청을 보내지 않고 바로 실제 요청을 보낸다.
          • Preflight 응답이 가져야하는 특징
            • 응답 코드는 200 대여야 한다.
            • 응답 Body는 비어있는 것이 좋다.
          • Preflight가 필요한 이유 : CORS를 모르는 서버의 안전을 위해서
            • delete 같은 요청이 왔을 때 이를 바로 처리한 후 브라우저에 CORS 오류를 발생시키면 서버는 이미 DB 내용을 지웠기 때문에 늦는다. 따라서 미리 preflight를 보내보고 cors 오류를 발생시키고 본 요청을 보내지 않아야 서버도 안전하다.
      • Simple Request : Preflight 없이 바로 실제 요청을 보낸다.
        • 조건
          • 메서드 : GET, POST, HEAD
          • Content-Type : application/x-www-form-urlencoded, multipart/form-data, text/plain
          • Header : Accept, Accept-Language, Content-Language, Content-Type
      • 인증정보 포함 요청(Credentialed) : 인증 관련 헤더 정보(쿠키, 토큰..)가 포함된 요청
        • 클라이언트는 credentials : include 를 설정하여 요청
        • 서버는 Access-Control-Allow-Credentials: true를 설정
          • Access-Control-Allow-Origin: * 이 아니어야 한다.
  • CORS 오류 해결방법
    • 프론트 프록시 서버 설정 (개발환경)
      • 브라우저에서는 같은 출처로 보내도록 만들고, 프론트 서버에서 다른 출처로 보내게 만든다.
        • 브라우저 요청
          • origin: example.com:1000
          • target(FE Server): example:1000/api
            • 브라우저 입장에서는 같은 origin, target 이므로 cors 오류가 발생하지 않는다.
        • FE Server
          • origin: example:1000
          • target(BE Server): example:2000/api
    • 직접 헤더에 설정
    • 스프링 부트 설정