CORS 정리하기

Sheryl Yun·2022년 7월 23일
0
post-thumbnail

CORS란?

  • 교차 출처 자원 공유(Cross Origin Resource Sharing)의 약자
  • 브라우저가 SOP 정책을 어겼다고 판단했을 때 발생시킴

SOP(Same Origin Policy) 정책
안전(XSS 방지 등)을 위해 같은 출처에서 온 요청만 받겠다고 하는 정책

요청 종류

simple requests와 Preflighted requests가 있다.

1. simple requests

다음과 같은 HTTP Method와 HTTP Header를 포함한 요청

HTTP Method

  • GET, POST, HEAD

HTTP HEADER

  • ACCEPT
  • Accept-Language
  • Content-Language
  • Content-Type
  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

위 Method와 Header의 조건을 충족하지 않으면 브라우저는 Simple requests가 아니라고 판단하고 대신 Preflighted requests를 날린다.

2. Preflighted requests

  • 클라이언트가 서버로 요청을 보내기 전에 OPTIONS 메서드를 통해 이 요청을 보내도 되는지 확인하는 것
  • 사전 요청이 통과되어야 비로소 서버에 본 요청을 보냄

요청 헤더

  • Origin: 원래 보내려고 했던 요청의 Origin (ex. https://www.naver.com)
  • Access-Control-Request-Method: 원래 보내려고 했던 요청의 Methods (ex. PUT, DELETE)
  • Access-Control-Request-Headers: 원래 보내려고 했던 요청의 Headers

응답 헤더

서버가 응답 헤더를 통해 사용 가능한 Origin, Method 등을 알려준다.

  • Access-Control-Allow-Origin: https://foo.example
  • Access-Control-Allow-Methods: POST, GET, OPTIONS
  • Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
  • Access-Control-Max-Age: 86400

Access-Control-Allow-Origin

보통 개발 서버나 급하게 테스트할 경우 * 을 많이 입력해서 주지만, 현재 서비스 중인 웹 사이트의 Origin이나 프록시 서버의 Origin을 입력하는 것이 바람직하다.

Access-Control-Allow-Methods

여기도 * 대신 구체적인 메서드를 명시하는 게 좋다. CORS 요청 중에 원하지 않는 메소드가 허락될 수 있고 무엇보다도 모든 브라우저에 대응하지 못하기 때문이다.
Chrome만 서비스하면 크게 상관 없지만 보통 대부분의 서비스들은 다양한 웹 브라우저 환경을 고려해야 한다.

Access-Control-Allow-Headers

여기서 * 을 쓰면 2가지 문제점이 있다.

  • 위와 같은 브라우저 호환성 이슈 문제
  • 로그인 유저의 인증 용도로 쓰이는 Authorization Header가 * 항목에 포함되지 않음

따라서 Headers도 *이 아닌 구체적으로 선언해주도록 한다.

Access-Control-Max-Age (초 단위)

한번 preflight 요청에 대한 응답을 받으면 일정 기간이 지날 때까지 다시 preflight 요청을 하지 않도록 하는 옵션이다.

  • 예를 들어 이 옵션에 3600을 입력하면 1시간(60분 = 3600초) 동안 preflight 요청을 추가적으로 보내지 않는다.

쿠키를 사용한다면 credentials 설정하기

HTTP 과정에서 쿠키를 이용한 로직이 있다면 프론트와 서버에 credentials 관련 설정을 해줘야 한다.

프론트엔드 설정

통신 함수(fetch, axios) 사용 시 option에 추가

fetch(url, { credentials: 'include' })

또는
axios.defaults.withCredentials = true;

백엔드 설정

응답 헤더에 관련 설정 추가

res.setHeader('Access-Control-Allow-Credentials', 'true');

출처: CORS 이젠 끝내보자

profile
데이터 분석가 준비 중입니다 (티스토리에 기록: https://cherylog.tistory.com/)

0개의 댓글