본문 바로가기

우아한테크코스/테코톡

CORS

2021-06-16글

[10분 테코톡] 🌳 나봄의 CORS을 들으며 정리한 글입니다.

배경 지식

SOP(Same Origin Policy)

  • 다른 출처의 리소스를 사용하는 것에 제한하는 보안 방식

왜 SOP?

  • CSRF Attack 때문!
  • 사용자는 인증 토큰을 가지고 있는 상태
  • 해커가 만든 주소로 이동하는데, 여기다 해커는 악의적인 스크립트를 심음
  • 해커는 인증 토큰을 가지고 악의적인 스크립트를 실행할 수 있음
  • 만약 송금이나 민감한 정보를 건드릴 시 굉장히 위험

여기서 SOP가 위력을 발휘

  • 웹사이트 입장에서는 자신과 다른 출처를 가지기 때문에 위 요청은 받을 수 없다고 판단

출처(Origin)란?

  • Protocol, Host, Port 세가지가 같아야 같은 출처라고 판단
  • 참고로 인터넷 익스플로어는 출처판단에 Port가 포함되지 않음

🤔 그러면 다른 출처 리소스가 필요하면 어떻게해??

CORS!!


CORS란?

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. - MOZILLA

CORS 접근제어 시나리오

단순 요청 (Simple Request)

  • Preflight 요청 없이 바로 요청

조건을 모두 만족해야 함

  • 메서드는 아래만 허용
    • GET, POST, HEAD
  • Content-Type은 아래만 허용
    • application/x-www-form-urlencoded
    • multipart/form-data
    • test/plain
  • Header는 아래만 허용
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type

프리플라이트 요청 (Preflight Request)

  • 쉽게 말하자면 사전 확인 작업
  • OPTIONS 메서드를 통해 다른 출처의 리소스에 요청이 가능한지 확인하는 작업
  • 요청이 가능하면 실제 요청(Actual Request)을 보냄

  • 클라이언트가 사전 요청을 보냄
  • 서버는 이에 응답
  • 만약 이 요청이 거부된다면 Actual Request는 보내지 않음

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대여야 함
  • 응답 바디는 비어있는 것이 좋음

왜 Preflight가 필요할까?

  • 사전 요청이 없으면 서버는 요청에 대해 모든 로직을 일단 수행함
  • 그리고 나서 Origin을 판단
  • 일단 로직이 수행된 후 CORS 이슈가 발생
  • 사전 요청이 있으면 요청을 수행하기 전 Origin을 판단
  • 때문에 서버는 안전히 잘 지켜짐

인증정보 포함 요청 (Credentialed Request)

  • 인증 관련 헤더를 포함할 때 사용하는 요청
  • 클라이언트 측
    • credentials : include
  • 서버 측
    • Access-Control-Allow-Credentials : true
    • 대신 이러면 아래와 같은 조건이 충족되어야 함
조건
  • Access-Control-Allow-Origin에는 *를 사용할 수 없으며, 명시적인 URL이어야함
  • 응답 헤더에는 반드시 Access-Control-Allow-Credentials: true가 존재해야함
🚨 Access to fetch at ’https://localhost:8080’ from origin ’http://localhost:8000’ has been blocked by CORS policy: The value of the ‘Access-Control-Allow-Origin’ header in the response must not be the wildcard ’*’ when the request’s credentials mode is ‘include’.

CORS 해결하기!

프론트 프록시 서버 설정(개발 환경)

  • 브라우저 입장에서는 origin과 target이 같기 때문에 same origin

추가

스프링 부트 이용

@CrossOrigin 어노테이션 사용

참고

  • Origin을 설정 안해주면 Default 값으로 모든 Origin을 허용함
  • 때문에 설정해주는 것이 좋음

전역으로 설정하는 방법 - Config


참고 자료

'우아한테크코스 > 테코톡' 카테고리의 다른 글

제네릭  (0) 2021.09.25
Servlet과 Spring  (0) 2021.08.06
Cache  (0) 2021.08.06
MVC 패턴  (0) 2021.08.06
DTO와 VO  (0) 2021.08.06