-
CORS란?개발/Front-end 2021. 8. 2. 23:38
CORS
SOP(Same-Origin Policy)
동일 출처 정책으로 한 출처(Origin)에서 로드된 문서나 스크립트가 다른 출처의 자원과 상호 작용을 못하도록 제한하는 것을 말한다.
이 정책으로 의해 XMLHttpRequest 객체로 특정 웹 페이지 접근할 때, 해당 페이지와 동일한 출처의 페이지에만 접근이 가능한 것이다.동일 출처(Origin)란?
Protocol
,Host
,Port
가 모두 같을 때 동일 출처다.CORS(Cross-Origin Resource Sharing)
다른 출처의 자원과의 상호 작용을 위해 SOP 예외 조건으로 CORS 정책이 생겼다.
CORS 정책을 위반하지 않는 다면 다른 출처의 리소스를 공유할 수 있다.어떻게 CORS 정책을 위반했는 지 판단할까?
출처를 비교하는 로직은 서버가 아닌 브라우저에 구현되어 있다.
CORS 정책에 위반하는 리소스 요청을 하면 서버가 같은 출처만 받겠다는 로직이 있는 경우가 아니면 서버는 정상적인 응답을 하고,
이후 브라우저가 응답 헤더를 분석하여 CORS 정책 위반이라고 판단되면 그 응답을 사용하지 않는다.- HTTP 프로토콜을 사용하여 리소스 요청을 한다.
- 이 때 브라우저는 요청 헤더의 Origin 필드에 출처를 담아 보낸다.
- 서버는 응답 헤더의 Access-Control-Allow-Origin 필드에 해당 리소스에 대한 접근이 허용된 출처를 담아 응답한다.
- 브라우저는 응답의 Access-Control-Allow-Origin 과 요청 헤더의 Origin을 비교하여 응답이 유효한 지 판단한다.
CORS, SOP 정책 존재 이유는?
다른 출처의 애플리케이션이 서로 통신하는 것에 대해 아무런 제약도 존재하지 않으면
해커가CSRF(Cross-Site Request Forgery)
나XSS(Cross-Site Scripting)
와 같은 방법으로 앱 코드가 실행된 것처럼 꾸며
사용자의 정보를 탈취하기 쉬워진다. 또 개발자가 신경써야 할 일이 늘어난다.Preflight, Simple, Credential Request 에서 CORS
1. Preflight Request
preflight는 브라우저가 본 요청을 보내기 전에 보내는 예비 요청을 말하며 HTTP METHOD 중 OPTIONS를 사용한다.
예비 요청은 본 요청을 보내기 전에 브라우저 스스로 안전한 요청인지 확인하는 과정이다.2. Simple Request
예비 요청 없이 바로 본 요청을 보내는 경우로 발생 조건이 까다로워 해당 요청이 발생하는 경우는 드물다.
- 요청 메소드: GET, HEAD, POST 중 하나만 사용 가능
- Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width를 제외한 헤더를 사용 불가
- 만약 Content-Type를 사용하는 경우에는 application/x-www-form-urlencoded, multipart/form-data, text/plain만 허용
3. Credentialed Request
다른 출처 간 통신에서 좀 더 보안을 강화하고 싶을 때 사용한다.
fetch(url, { credentials: 'include', // 요청에 인증과 관련된 정보를 포함하겠다. });
위와 같이 설정하면 요청 시 브라우저의 쿠키 정보가 함께 보내진다.
단,
credentials: include
를 사용하면 브라우저는Access-Control-Allow-Origin: *
처럼 와일드 문자를 허용하지 않게 된다.
인증 정보가 담겨있는 상태에서 다른 출처에 요청을 하고 싶다면 아래 두가지를 추가해야 CORS 정책 위반을 피할 수 있다.Access-Control-Allow-Origin
에는 *를 사용할 수 없으며, 명시적인 URL이어야한다.- 응답 헤더에는 반드시
Allow-Control-Allow-Credentials: true
가 존재해야한다.
CORS 해결 방법
- 서버에서 Access-Control-Allow-Origin 헤더에 알맞은 값 세팅하기
- Webpack Dev Server로 리버스 프록싱
module.exports = { devServer: { proxy: { '/api': { target: 'https://api.evan.com', changeOrigin: true, pathRewrite: { '^/api': '' }, }, } } }
'개발 > Front-end' 카테고리의 다른 글
DOM API란? (0) 2021.08.02 SSR vs CSR vs SPA (0) 2021.08.02 부트스트랩의 sr-only 클래스가 하는 일 (0) 2021.08.02 가깝고도 먼 HTML (0) 2021.08.02 GraphQL 알아보기 (0) 2021.08.02