[F-Lab 모각코 챌린지 33일차] CORS Cross-Origin Resource Sharing (2)

Nami·2023년 7월 3일
0

66일 포스팅 챌린지

목록 보기
33/66

저번 포스팅에서는 간단한 배경과 SOP 등에 대해 알아보았다. 기본적인 흐름은 간단하지만, CORS가 동작하는 방식은 한 가지가 아니라 세 가지의 시나리오에 따라 변경된다. 이번엔 CORS의 동작방식에 집중하고, 오류 발생시 어떻게 해결하거나 예방할 수 있을지 알아보겠다.


CORS Cross-Origin Resource Sharing

동작방식

Preflight Request

브라우저는 요청을 한번에 보내지 않고 예비 요청과 본 요청으로 나누어서 서버로 전송한다. 이때 브라우저가 본 요청을 보내기 전에 보내는 예비 요청을 Preflight라고 부르는 것이며, 이 예비 요청에는 HTTP 메서드 중 OPTIONS 메서드가 사용된다.

  1. HTTPHeader(Access-Control-Request-Method)
  2. HTTPHeader(Access-Control-Request-Headers)
  3. HTTPHeader(Origin)

총 3가지의 HTTP request headers를 사용하는 HTTPMethod(OPTIONS) 요청이다.

OPTION method의 헤더

  1. Access-Control-Request-Method
  • 실제 요청에서 사용될 HTTP 메서드를 지정.
  • 프리플라이트 요청에서 클라이언트가 서버에게 어떤 메서드를 사용할 것인지를 알리는 역할을 함.
  1. Access-Control-Request-Headers
  • 실제 요청에서 사용될 헤더를 지정.
  • 클라이언트가 실제 요청에서 어떤 커스텀 헤더를 사용할 것인지 서버에게 알리는 역할.

역할?

본 요청을 보내기 전에 브라우저 스스로 이 요청을 보내는 것이 안전한지 확인하는 것.

  1. fetch API를 사용하여 브라우저에게 리소스를 받아오라는 명령을 내린다.
  2. 브라우저는 서버에 예비 요청을 먼저 보낸다.
  3. 예비 요청에 대한 응답으로 현재 자신이 어떤 것을 허용하고 금지하는지 알게된 정보를 응답 헤더에 담아서 브라우저에게 다시 보낸다.
  4. 자신이 보낸 예비 요청과 서버가 응답해준 허용 정책을 비교한다.
  5. 안전하다고 판단되면 같은 엔드포인트로 다시 본 요청을 보냄.
  6. 이후 서버각 요청에 대한 응답을 하면 브라우저는 최종적으로 응답 데이터를 JS에게 넘겨준다.

생략 가능

일반적으로 브라우저에서 자동으로 발생된다. 그래서 요청을 직접 작성할 필요가 없고, 필요한 경우에만 나타나므로 단순한 요청(Simple Requests)의 경우에는 사전 요청이 생략된다.

Simple Request

예비 요청을 보내지 않고 바로 서버에게 본 요청을 보낸 후, 서버가 이에 대한 응답의 헤더에 Acces-Control-Allow-Origin 등과 같은 값을 보내주면 그때 브라우저가 CORS 정책 위반 여부를 검사하는 방식.

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

  • GET, HEAD, POST 중 하나의 메서드
  • User-Agent가 자동으로 설정한 헤더 외.
  • Content-Type 헤더 중 다음의 값
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

Credentialed Request

자격 증명을 포함한 요청. 다른 출처간 통신에서 보안을 강화하고 싶을 때 사용하는 방법.

기본적으로 브라우저가 제공하는 비동기 리소스 요청 API인 XMLHttpRequest 객체나 fetch API는 별도의 옵션 없이 브라우저의 쿠키 정보나 인증과 관련된 헤더를 함부로 요청에 담지 않는다. 이때 요청에 인증과 관련된 정보를 담을 수 있게 해주는 옵션이 바로 credentials 옵션이다. HTTP Cookies와 HTTP Authentication 정보를 인식한다.

충족 조건

  1. 서버는 Access-Control-Allow-Credentials 헤더를 true로 설정하여 클라이언트가 인증 정보를 포함한 요청을 허용해야 한다.
  2. 클라이언트는 요청을 보낼 때 credentials 옵션을 include로 설정하여 브라우저에게 인증 정보를 포함시킬 것을 명시해야한다.
  • Access-Control-Allow-Origin*는 사용할 수 없으며 명시적인 URL이어야 한다.
fetch('https://api.example.com/data', {
  method: 'GET',
  credentials: 'include' // 인증 정보를 포함하기 위해 credentials 옵션을 include로 설정
})
  .then(response => {
    // 응답 처리
  })
  .catch(error => {
    // 오류 처리
  });

CORS 헤더 옵션


fetch('https://api.example.com/data', {
  method: 'GET',
  headers: {
    'Origin': 'https://www.example.com', // 요청을 보내는 출처
    'Access-Control-Request-Method': 'GET', // 요청하는 HTTP 메서드
    'Access-Control-Request-Headers': 'Authorization, Content-Type' // 요청하는 헤더들
  },
  mode: 'cors' // CORS 모드로 요청 보내기
})
  .then(response => {
    // 응답 처리
  })
  .catch(error => {
    // 오류 처리
  });
  • Origin: 요청을 보내는 출처. 클라이언트는 이 헤더를 설정하여 자신의 출처를 서버에 알림.
  • Access-Control-Request-Method: 요청하는 HTTP 메서드를 나타낸다. 클라이언트가 실제 요청을 보내기 전에 이 헤더를 사용하여 서버에게 허용되는 메서드를 물어봄.
  • Access-Control-Request-Headers: 요청하는 헤더들을 나타낸다. 클라이언트가 특정 헤더들을 실제 요청에 포함시키기 전에 이 헤더를 사용하여 서버에게 허용되는 헤더들을 물어봄.

Access-Control-Allow-Origin 세팅하기

  • CORS 정책 위반으로 인한 문제를 해결하는 가장 대표적인 방법.
  • Access-Control-Allow-Origin 헤더에 정석대로 서버에서서 알맞은 값을 세팅해주는 것.
  • 와일드 카드로 쓰이는 *를 사용하여 세팅한다면 모든 출처에서 오는 요청을 받겠다는 의미로 심각한 이슈가 생길 수 있음.

CORS 정책 위반 관련하여 오류를 예방할 수 있는 방법의 경우엔, 아직 스스로 실무에 대한 경험이 없어 공부를 해도 이해를 할 수 없는 영역이라 생략하겠다.


참조 ✅

0개의 댓글