[JS] CORS 정리 및 오류 해결

SJ·2022년 6월 24일
0

라이브 방송과 라이브 채팅 서버간 데이터 처리 과정에서 해당 문제를 겪고 공부해 정리한 내용!




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 기본 동작 과정

  1. 클라이언트에서 HTTP 요청의 헤더에 Origin을 담아 전달.

  2. 서버는 응답헤더에 Access-Control-Allow-Origin을 담아 전달.

  3. 클라이언트에서, 자신이 보냈던 요청의 Origin과 서버가 보낸 Access-Control-Allow-Origin을 비교.

  • 유효하지 않다면(비교 했을 때 다르다면) 그 응답을 사용하지 않는다. 즉, CORS정책으로 Origin을 비교하는 것은 브라우저에서 처리하기 때문에 서버에서 정상적으로 응답을 하였어도 브라우저가 응답을 CORS 위반이라고 분석하면 그 응답을 사용할 수가 없다.




### CORS 3가지 시나리오

3가지의 시나리오가 있지만 아래 사이트를 참조하여 작동방식을 확인하고 이 글에서는 내가 가장 많이 사용한 단순 요청만 다뤄보겠다.

링크텍스트

먼저 요청 메소느는 GET, HEAD, POST 중 하나여야 하고 유저 에이전트가 자동으로 설정한 헤더외에 수동으로 설정 가능한 헤더는 Fetch 명세에 CORS-safelisted request-header로 정의한 것만 사용가능하다.

  1. Accept
  2. Accept-Language
  3. Content-Language
  4. Content-Type
  5. DPR
  6. Downlink
  7. Save-Data
  8. Viewport-Width
  9. Width
  • Content-Type을 사용하는 경우 다음의 값만 사용이 허용된다.
  1. application/x-www-form-urlencoded
  2. multipart/form-data
  3. 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
profile
효율적이고 효과적이게

0개의 댓글