- 전체
- HTML
- Web Design (웹디자인)
- XE 응용 개발
- wordpress plugin dev
- Javascript & JavaScript Application
- MEAN Stack : full stack javascript
- angular js & ionic framework
- bootstrap
- WebGL, Three.js and Babylon.js
- restful api design
- mobile web
- node.js 응용
- Cloud Service 응용
- 웹 어셈블리 개발 [WASM, WebAssembly]
- 마이크로서비스, MSA (microservice architecture)
- WebGL / WebGPU
- next.js 개발
- micro frontend (마이크로프론트앤드)
JavaScript [JavaScript] [JS] CORS 정리 및 오류 해결
2023.05.09 15:05
[JavaScript] [JS] CORS 정리 및 오류 해결
CORS(Cross Origin Resource Sharing)
cors 정책은 응답받는 리소스들을 검사하는 기능을 한다.
웹 개발을 할 때 필수적으로 알아야할 정책이므로 정리해보자
가장 간단한 예시로는 서로 다른 두 로컬서버에서
한 서버에서 다른 서버로 GET, POST 같은 요청을 보냈을 때 응답을 핸들링하려고하면
Access to fetch at 'url' from origin 'url2' has been blocked by CORS policy : No 'Access-Control-Allow-Origin' header is present on the requested rescource. If an opaque respose serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
이와 같은 에러를 볼 수 있다.
이는 HTTP 요청에 대해서 어떤 요청을 하느냐에 따라 다른 특징을 가지고 있기 때문인데
HTML 은 기본적으로 Cross-Origin 정책을 따르고 link 태그에서 다른 origin의 소스에 접근이 가능하다.
하지만 XMLHttpRequest, Fetch API 등 script 태그 내에서는 Same-Origin 정책을 따르므로 자바스크립트는 서로 다른 도메인에 대한 요청을 보안상 제한하고 있어서 오류가 나는 것이다.
** Origin이란
출처란 서버의 위치를 의미하는 url을 보면
http://www.sample.com:3001/login?query=test#me
순서대로
protocol, host, port, path, query string, fragment 를 의미하고
출처는 이중에서 protocol + host + port 까지 합친 것을 의미한다.
console.log(location.origin); // http://www.sample.com:3001
- 실제로 라이브 방송 client쪽 서버와 채팅서버를 따로 분리시킨 상황에서 client에서 채팅서버와 데이터를 주고 받을때 이와 같은 CORS 오류 때문에 추가세팅을 해주기 전까진 데이터를 주고 받을 수 없었다.
CORS 기본 동작 과정
-
클라이언트에서 HTTP 요청의 헤더에 Origin을 담아 전달.
-
서버는 응답헤더에 Access-Control-Allow-Origin을 담아 전달.
-
클라이언트에서, 자신이 보냈던 요청의 Origin과 서버가 보낸 Access-Control-Allow-Origin을 비교.
- 유효하지 않다면(비교 했을 때 다르다면) 그 응답을 사용하지 않는다. 즉, CORS정책으로 Origin을 비교하는 것은 브라우저에서 처리하기 때문에 서버에서 정상적으로 응답을 하였어도 브라우저가 응답을 CORS 위반이라고 분석하면 그 응답을 사용할 수가 없다.
### CORS 3가지 시나리오
3가지의 시나리오가 있지만 아래 사이트를 참조하여 작동방식을 확인하고 이 글에서는 내가 가장 많이 사용한 단순 요청만 다뤄보겠다.
먼저 요청 메소느는 GET, HEAD, POST 중 하나여야 하고 유저 에이전트가 자동으로 설정한 헤더외에 수동으로 설정 가능한 헤더는 Fetch 명세에 CORS-safelisted request-header로 정의한 것만 사용가능하다.
- 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
해결방안
1. Chrome 확장 프로그램 이용
크롬에서는 CORS 문제를 해결하기 위한 확장 프로그램을 제공하는데
'Allow CORS: Access-Control-Allow-Origin을 설치하고 활성화하면, 로컬환경에서 API를 사용할때 CORS 문제를 해결할 수 있다.
하지만! 모든 사용자가 해당 브라우저에서 다음과 같은 작업을 하고 사용하는 경우는 없기 때문에 서버쪽에서 작업을 해주는 것이 낫다고 생각한다.
2. 서버에서 Access-Control-Allow-Origin 세팅하기
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Credentials', 'true'); //쿠기 주고 받기 허용
이와 같이 *을 사용하면 모든 Origin에서 오는 요청을 허용하므로 보안상으로는 취약하다.
res.setHeader('Access-Control-Allow-Origin', 'http://www.sample.com');
이렇게 출처를 명시해주면 좋다.
이 헤더는 Nginx나 Apache 같은 서버 엔진의 설정에서도 추가 가능하지만 소스 코드 내에서 응답 미들웨어 등을 사용하여 세팅하는 것이 비교적 간단하다.
- 헤더의 Access-Control-Allow-설정들
//헤더에 작성된 출처만 브라우저가 리소스 접근 허용
Access-Control-Allow-Origin : url
//리소스 접근을 허용하는 http 메서드 지정
Access-Control-Request-Methods: GET, POST, PUT, DELETE
//서버에서 응답 헤더에 추가해 줘야 브라우저의 자바스크립트에서 헤더에 접근 허용
Access-Control-Expose-Headers: Authorization
//60초 동안 preflight 요청을 캐시하는 설정
Access-Control-Max-Age : 60
// js 요청에서 credentials 가 inclue일때 요청에 대한 응답을 할 수 있는지
Access-Control-Allow=Credentials: true
[출처] https://velog.io/@sjc0829/JS-CORS-%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0-vla2dd8c
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.