sitelink1 https://blog.naver.com/innogrid/222462844944 
sitelink2  
sitelink3  
sitelink4  
extra_vars4  
extra_vars5  
extra_vars6  

1. CORS 개요

CORS (교차 출처 자원 공유)는 보안 상의 이유로

JavaScript에서 보내는 교차 출처(자신과 다른 출처) HTTP 요청을 제한하기 위한 정책입니다.

대다수 브라우저에는 CORS가 적용되어 있는데

이는 자신의 출처와 동일한 리소스만 불러올 수 있도록 하여, 악의적인 자원 접근과 탈취를 막기 위함입니다.

 

cors01.jpg

[그림 1] CORS 개요

2. CORS 에러

웹을 개발하면서 아래와 같은 에러 메시지를 한번쯤 보셨을 것 같습니다.

CORS 에러가 발생하는 이유는 [CORS 개요]에서 소개했듯이

JavaScript 코드 상에서 동일한 출처가 아닌 곳에서 요청을 하였기 때문입니다.

아래의 에러 내용을 살펴보면

"http://localhost:3000 출처에서 보낸 https://www.example.com 의 자원 접근 요청을 CORS 정책에 의해 차단되었습니다."

라는 문구를 확인할 수 있습니다.

Access to fetch at ‘http://www.example.com’ from origin ‘http://localhost:3000’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.
/* * main.js * local에서 main.js가 http://www.example.com에 데이터를 요청함 * 출처가 다르기 때문에 CORS 에러 발생 */ $.get('http://www.example.com', function (data) { alert('Data Loaded: ' + data); });

3. CORS 동작 과정

CORS는 브라우저에서 이루어집니다. 때문에, 브라우저의 옵션을 수정하면 CORS를 회피할 수 있습니다.

예를 들어 크롬 브라우저에서 --disable-web-security 옵션을 추가하면 CORS 에러 없이 여러 출처의 리소스에 대해 접근할 수 있습니다.

그렇다면, 브라우저는 어떻게 CORS를 동작하고 있을까요?

CORS는 Preflight Request, Simple Request 두 가지 방식으로 동작됩니다.

Preflight Request, Simple Request에 대해 한번 알아봅시다.

● Preflight Request

본 요청을 보내기 이전에 보내는 예비 요청을 Preflight라고 부릅니다.

Preflight는 HTTP의 OPTIONS 메소드를 이용해 서버에 보내집니다.

이러한 예비 요청을 통해 본 요청을 보내기 전, CORS를 위반하고 있는지를 확인합니다.

Preflight에 대한 서버 응답이 안전하다면 브라우저는 본 요청을 서버에 다시 보냅니다.

 

cors02.jpg

[그림 2] Preflight Request 동작

● Simple Request

Simple Request (단순 요청)는 Preflight Request 방식과 달리 예비 요청을 보내지 않습니다.

대신 Access-Control-Allow-Origin 헤더를 이용해 CORS 위반 여부를 검사합니다.

클라이언트의 요청에 대해 서버는 Access-Control-Allow-Origin 헤더와 함께 응답합니다.

Access-Control-Allow-Origin 헤더에는 CORS 정책이 담겨있고

브라우저는 Access-Control-Allow-Origin 헤더의 내용을 토대로 정책을 위반했는지 확인합니다.

이상이 없다면 본 요청을 서버에 보냅니다.

 

SE-694362eb-da00-41e7-8a0a-0c628824979b.png

[그림 3] Simple Request 동작

4. CORS 해결 방법

CORS는 서버, 클라이언트 한쪽만 의 적용으로 해결할 수 있습니다.

서버, 클라이언트 각각에서 CORS를 처리하는 대표적인 방법 두 가지를 소개합니다.

(다만, 서버에서 CORS 정책을 제어하는 것을 권장합니다.)

● @CrossOrigin 어노테이션 이용 (API)

스프링 기준, 스프링 4.2 이상부터 지원되는 @CrossOrigin을 이용하여 CORS 정책을 설정할 수 있습니다.

Controller에 어노테이션을 추가하면 적용됩니다.

• @CrossOrigin : 모든 도메인, 모든 요청 방식에 대해 허용.

• @CrossOrigin(origins = "http://www.example1.com, http://www.example2.com") : http://www.example1.com, http://www.example2.com 도메인에 대해서만 허용.

@CrossOrigin public class ProjectController { @GetMapping(value="/projects/list", produces = "application/hal+json") public ResponseEntity<List<Project>> getProjectList(@ModelAttribute KeystoneProject project){ return ResponseEntity.ok(projectService.getProjectList(project)); } }

● 프록시 이용 (Client)

CORS 에러는 근본적으로 자신과 다른 출처에서 HTTP 요청을 하였을 때 발생한다는 점을 기억해 보면

자신의 출처를 프록싱하면 CORS를 회피할 수 있을 것 같습니다.

클라이언트는 이 같은 아이디어로 CORS 에러를 해결합니다.

프록싱을 통해 자신의 출처를 CORS가 허용되는 출처로 바꿔 HTTP 요청을 하는 것이죠.

프록싱을 하면 최소한의 설정으로 CORS를 회피할 수 있어 개발 시 이용되곤 합니다.

참고

⦁ https://medium.com/@buddhiv/what-is-cors-or-cross-origin-resource-sharing-eccbfacaaa30

⦁ https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

⦁ https://evan-moon.github.io/2020/05/21/about-cors/#preflight-request

⦁ https://velog.io/@roh-j/CORS-Cross-Origin-Resource-Sharing%EA%B0%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C

 

 

번호 제목 글쓴이 날짜 조회 수
237 json 데이터 내의 변수명에 prefix 로 type 표현하기 황제낙엽 2024.04.15 0
236 fetch() 함수 사용 예제 file 황제낙엽 2023.11.23 1
235 현재 document 의 host 와 port 를 얻는 방법 황제낙엽 2023.10.03 1
234 (Bard) FileReader 로 여러개의 파일을 read 하는 법 file 황제낙엽 2023.08.23 0
233 How to build a file upload service with vanilla JavaScript file 황제낙엽 2023.08.22 0
232 (Bard) JavaScript로 JSON 배열을 작성하는 방법 황제낙엽 2023.08.21 0
231 모바일 브라우저에서 file input element 를 이용하여 여러장의 이미지를 서버에 전송하려 할때 황제낙엽 2023.08.21 0
230 navigator.mediaDevices 황제낙엽 2023.08.21 1
229 Barcode Detection API 황제낙엽 2023.08.06 6
228 정규식을 이용한 이메일 검증 스크립트 file 황제낙엽 2023.06.25 0
227 체크박스에 체크된 항목 개수 구하기 황제낙엽 2023.06.10 1
226 JSON 클래스가 지원하는 function 황제낙엽 2023.03.31 1
225 (Copilot) JSON 객체의 내부 데이터 리스트 길이를 구하는 방법 황제낙엽 2023.03.30 2
224 배열에 대한 루프문 조회 (loop iterator) 황제낙엽 2023.03.01 3
223 (Copilot) 바닐라 스크립트가 뭐지? 황제낙엽 2023.02.24 7
222 CryptoJS 를 이용한 암호화 황제낙엽 2023.02.15 1
221 [URLSearchParams] URL 파라미터(매개변수) 값 가져오기 file 황제낙엽 2023.02.02 0
220 Fetch API (CORS 극복을 위한 노력) 황제낙엽 2021.12.05 26
219 두 서버의 자원을 접근하는 클라이언트 프레임웍(Next.js)에서의 CORS오류 file 황제낙엽 2021.12.05 228
» CORS 의 내용과 이에 대한 우회 방안들 file 황제낙엽 2021.12.05 139