CORS

똔의 기록·2022년 7월 26일
0
post-thumbnail

프론트엔드 개발할 때 어김없이 마주했던 cors 에러, 그때는 이게 무슨 에러인지도 모르고 그냥 크롬에서 웹 시큐리티를 잠시 해제해주어서 해결했던 기억이 있다.(보안에 매우 안좋긴함, 다른 방법으로는 CORS 프로그램을 깔아주는 것도 있었다.)

CORS 에러는 왜 일어나는걸까?

SOP (Same Origin Policy)

먼저 SOP는 다른 출처의 리소스를 사용하는 것을 제한하는 보안 방식이다.
여기서 출처는 URL의 Protocol, Host, Port로 구분한다.

http://velog.io:80를 예시로 들자면
[http : 프로토콜, velog.io : 호스트, 80 : 포트]

중간에 해커가 클라이언트에게 다른 출처 링크를 보내 데이터를 받으려고 할 때 토큰 만으로는 서버가 구별하기 어렵기 때문에 요청의 출처가 다른지 알아보아야 한다.

요청의 출처가 다르다면 Cross Origin SOP에 위반이라고 한다.
하지만 외부 라이브러리도 사용해야 하는데 요청과 리소스를 매번 동일한 출처로만 받을 수는 없다.

이 때 필요한 것이 CORS이다.

CORS (Cross-Origin Resource Sharing)

여기서 CORS는 타 도메인 간에 자원을 공유할 수 있게 해주는 것이다. Cross-Origin Resource Sharing 표준은 웹 브라우저가 사용하는 정보를 읽을 수 있도록 허가된 출처 집합을 서버에게 알려주도록 허용하는 특정 HTTP 헤더를 추가함으로써 동작한다.

어떤 요청이 CORS를 사용하나요?

교차 출처 공유 표준은 다음과 같은 경우에 사이트간 HTTP 요청을 허용한다.

  • XMLHttpRequest와 Fetch API 호출.
  • 웹 폰트(CSS 내 @font-face에서 교차 도메인 폰트 사용 시), 서버가 크로스 사이트 로드 및 허용된 웹 사이트에서만 사용할 수 있는 트루타입 글꼴을 배포할 수 있도록 합니다.
  • WebGL 텍스쳐.
  • drawImage() (en-US)를 사용해 캔버스에 그린 이미지/비디오 프레임.
  • 이미지로부터 추출하는 CSS Shapes.

CORS 접근제어에 사용되는 3가지의 시나리오가 있다.

  • 단순 요청 (Simple Request)
  • 사전 요청 (Preflight Request)
  • 인증 요청 (Credentialed Request)

단순 요청 (Simple Request)

Preflight 요청 없이 바로 요청을 보낸다.
Simple Request는 아래와 같은 조건을 만족해야한다.

  • 메서드 : GET, POST, HEAD
  • Content-Type은 아래 셋 중 하나여야 한다.
    1) application/x-www-form-urlencoded
    2) multipart/form-data
    3) text/plain
  • 헤더 : Accept, Accept-Language, Content-Language, Content-Type 만 허용 한다.

사전 요청 (Preflight Request)

사전 요청은 OPTIONS 메서드를 통해 다른 도메인 리소스에 요청이 가능한지 확인하는 작업이다.
요청이 가능한 것을 확인하면 실제 요청을 보낸다.

Preflight Request

  • Origin : 요청 출처
  • Access-Control-Request-Method : 실제 요청의 메서드
  • Access-Control-Request-Headers : 실제 요청의 추가 헤더

Preflight Response

  • Access-Control-Allow-Origin : 허가 출처
  • Access-Control-Allow-Methods : 허가 메서드
  • Access-Control-Allow-Headers : 허가 헤더
  • Access-Control-Max-Age : Preflight 응답 캐시 시간

여기서 Preflight Response의 응답 코드는 200대여야하고 Body는 비어있는 것이 좋다.

인증 요청 (Credentialed Request)

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

클라이언트

쿠키 또는 JWT 토큰을 담아 보낼 경우 credentials : include 를 포함하여 보낸다.

서버

Access-Control-Allow-Credentials : true 해야 클라이언트의 인증 포함 요청에 허용이 가능하다.

CORS 해결 방법에는 세 가지가 있다.

  • 프론트 프록시 서버 설정
    프론트 서버에서 백엔드 서버로 요청을 보낼 때, 대상의 URL을 변경한다.
  • 직접 헤더 설정
    직접 헤더에 설정을 추가한다.
  • 스프링부트 설정
    설정 클래스를 만들고 WebMvcConfigurer을 구현하면 addCorsMappings란 메서드를 사용하여 CORS의 출처 및 설정 관리를 할 수 있다.

참고
https://velog.io/@frankle97/CORS%EB%9E%80
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

profile
Keep going and level up !

0개의 댓글