CORS(Cross-Origin Resource Sharing)

교차 출처 리소스 공유

 

Origin

예를 들어

https://www.imsseeong.tistory.com:443/manage/newpost/?type=post#foo

protocol host port path query string fragment
https:// www.imsseong.tistory.com :443 /manage/newpost ?type=post #foo

Origin(출처)는 protocol, host, port 까지 합한 것을 의미

 

SOP(Same-Origin Policy)

같은 출처에서만 리소스를 공유할 수 있다는 규칙을 가진 정책

예외적으로 CORS 정책을 지킨 리소스 요청은 허용

 

같은 출처와 다른 출처를 구분하는 법

URL의 구성 요소 중 scheme, host, port가 동일하면 같은 출처

예를 들어 

https://www.imsseeong.tistory.com:443 가 동일해야 한다.

 

CORS 동작

웹 클라이언트 어플리케이션이 다른 출처의 리소스를 요청할 때는 HTTP 프로토콜을 사용하여 요청을 보낸다.

이때 요청 헤더에 Origin 이라는 필드에 요청을 보내는 출처를 담는다.

Origin: https://www.imsseeong.tistory.com:443

이후 서버가 요청에 대한 응답을 할 때 응답 헤더의 Access-Control-Allow-Origin 값에 이 리소스에 접근 허용된 출처를 내려준다.

응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 Access-Control-Allow-Origin을 비교한 후

이 응답이 유효한 응답인지 아닌지를 결정한다.

 

1. Preflight Request 

본 요청을 보내기 전 예비 요청을 Preflight라고 부른다.

예비 요청에서는 HTTP 메소드 중 OPTIONS 메소드가 사용된다.]

Access-Control-Request-Headers Content-Type Access-Control-Request-Method

출처: https://evan-moon.github.io/2020/05/21/about-cors/

 

2. Simple Request

Preflight와 전반적인 로직은 같지만, 예비 요청이 존재하지 않음

특정 조건을 만족하는 경우에만 예비 요청을 생략할 수 있다.

  • 요청의 메소드는 GET, HEAD, POST
  • Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width를 제외한 헤더를 사용하면 안됨
  • 만약 Content-Type를 사용하는 경우에는 application/x-www-form-urlencoded, multipart/form-data, text/plain만 허용

 

3. Credentialed Request

인증된 요청을 사용하는 방법

인증과 관련된 정보를 담을 수 있게 해주는 옵션이 credentials

옵션 설명
same-origin(기본값) 같은 출처 간 요청에만 인증 정보를 담을 수 있다.
include 모든 요청에 인증 정보를 담을 수 있다.
omit 모든 요청에 인증 정보를 담지 않는다.

요청에 인증 정보가 담겨있는 상태에서 다른 출처의 리소스를 요청하게 되면 다음 두가지 검사 필요

  • Access-Control-Allow-Origin에는 * 사용 금지
  • 응답 헤더에는 반드시 Access-Control-Allow-Credentials: true 존재

 

@CrossOrigin

Spring에서 CORS를 적용할 수 있게 만드는 어노테이션

도메인을 설정하면 해당 도메인은 다른 Origin이지만 요청을 주고받을 수 있게 된다.

해당 API controller 상단에 추가해 주자

@CrossOrigin(origins = "http://localhost:8080")
@CrossOrigin(origins = {"http://localhost:8080", "https://imsseong.tistory.com"})

+ Recent posts