CORS 란?

박병관·2022년 1월 30일
0

우아한Tech

목록 보기
1/17
post-thumbnail

순서
1. CORS를 알기 전(feat SOP개념)
2. CORS
3. CORS 접근제어 시나리오
4. 심플 요청이 아닌 프리플라이트 요청을 사용하는 이유

유튜브 [10분 테코톡] 🌳 나봄의 CORS 의 내용

CORS를 알기 전(feat SOP개념)

CORS를 알기 전 SOP(Same Origin Policy)라는 개념에 대해 알아보자
SOP는 다른 출처의 리소스를 사용하는 것에 제한하는 보안 방식이다

출처(origin)

url구조

이 url구조에서 Protocol, Host, Port를 통해 출처가 같은지, 다른지(3중 무엇 하나라도 다르다면, 즉 Cross Origin)를 판단한다

즉 SOP는 다른 출처에서 리소스를 사용하는 것에 제한하는 보안 방식이고, 이 SOP는 출처를 확인해서 Cross Origin(다른 출처) 라고 판단할 수 있어서 요청을 받아들이지 않는 방법으로 보안에 도움이 된다

하지만 다른 출처의 리소스가 필요할 수 있다, 그래서 CORS에 들어간다

CORS

cors란 Cross-Origin Resource Sharing, 다른 출처의 자원을 공유하는 것이다

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

CORS 접근제어 시나리오

1. 프리플라이트 요청 - Preflight Request

option메서드를 통해 다른 도메인의 리소스 요청이 가능한지 확인 후 가능하면 실제 요청(Actual Request)를 보낸다
preflight request

Access-Control-Request-Method = 실제 요청의 메서드
Access-Control-Request-Headers = 실제 요청의 추가 헤더

본 요청을 보내기 전 서버한테 물어보는 것(요청을 보내도 되는지)이고, options 메서드를 통해 확인하다, 즉 2번 요청이 보내진다

  • 리소스적으로 2번씩 요청이 오가는 것은 좋지 않기 때문에, preflight응답에 대해서 브라우저가 캐싱을 해두고 다음 똑같은 요청을 보낼 때 캐싱이 된 것을 확인해 사전 요청을 미리 보내지 않을 수 있다
  • 프리플라이트 요청의 특징으로는 응답 코드가 200 대여야 한다, 응답 바디는 비어있어있는 것이 좋다

2. 단순 요청 - Simple Request

프리플라이트 요청과 다르게 바로 본 요청을 보내며 즉시 cross origin인지 확인 한다
simple requeset

서버의 대답에서 * 는 와일드카드 형식, 모든 origin을 허가한다는 뜻이다

단순 요청을 만족시키려면 다음 조건을 모두 만족시켜야 한다
1. get, post, head 메서드 중 하나여야만 한다
2. content type은 application/x-www-form-urlencoded , multipart/form-data , text/plain 이 3 중 하나여야 한다
3. 헤더는 Accept, Accept-Language, Content-Language, Content-Type 만 허용된다

클라이언트에서는 출처(origin)을 밝히고, 서버는 대답한다
위 사진을 예로 보면 클라이언트가 출처(foo.example)을 밝히고, 서버에서는 와일드카드 형식으로 모든 origin을 허가(foo.example도 허가)

3. 인증정보 포함 요청 - Credentialed Request

인증 관련 헤더를 포함(쿠키, jwt)할 때 사용하는 요청
쿠키, jwt 등을 클라이언트에서 자동으로 담아서 서버에 보내고 싶을 때 credentials 을 포함시키면 서버측까지 전달된다

서버측에서도 Access-Control-Allow-Credentials 를 true로 집어 넣어 줘야한다(추가로 모든 출처를 허용하면 안된다. 즉 Access-Control-Allow-Credentials : * 을 하면 안된다)

credentialed request

심플 요청이 아닌 프리플라이트 요청을 사용하는 이유

단순 요청은 한 번 요청 후 끝내는데, 왜 프리플라이트 요청으로 두 번 왔다가야할까?

그 이유는 CORS를 보르는 서버를 위해서다

서버에 단순 요청이 들어왔을 때 CORS인지 확인 후, 서버에서는 실행하고 CORS오류를 보내는 순서로 실행이 되는데, CORS를 모르는 서버에서 단순 요청이 들어왔을 때 서버에서 실행 후 브라우저에서 CORS오류를 보내기 때문에 보안상 문제가 될 수 있다

프리플라이트 요청을 사용하면 서버가 어떤 행동을 하지 않아도 브라우저가 사전에 CORS오류를 보낸다

CORS해결 방법

  1. 프론트 프록시 서버 설정(개발환경)
  2. 직접 헤더에 설정해주기(귀찮을수있음)
  3. 스프링 부트를 이용하기

정리하며 더 궁금한 점, 느낀점 🙃

  • cors 접근제어 시나리오 > 단순요청에서 content type 과 헤더의 accept, accpet-language ... 가 뭔지 궁금하다

  • CORS해결 방법에 대해 CORS에 대한 개념을 생각하며 알아보고 싶다

  • 해커톤을 할 때 CORS오류때문에 힘들었던 경험이 있었는데 출처(origin)와 같이 기본적인 개념, 보안을 담당(?)하고, mdn에서 '모든 사람이 읽어야 한다' 라는 말이 적혀있듯 기본적이지만 그만큼 중요한 개념이라는걸 느낄 수 있었다

profile
괴물신인

0개의 댓글