클라이언트에서 CORS해결하기

이수빈·2023년 6월 1일
1

CS

목록 보기
2/4
  • 카카오 인턴 관련 과제를 진행하던 중 CORS를 클라이언트에서 해결 했던 상황이 있어 이를 정리하고자 한다.

SOP(Same-Origin-Policy)란

  • 브라우저에서는 기본적으로 동일한 출처에서한 요청만 받아드리는 SOP정책을 따른다.

  • 여기서 Origin(출처)가 동일하다는 뜻은 => 프로토콜, 도메인, 포트번호가 동일하다는 것을 의미한다. 아래 예시를 보면 이해가 쉬울것이다.

http://example.com/ex //이 도메인에서 요청한다고 가정
http://example.com/user/1 // 성공, 프로토콜 http로 동일하고, example.com으로 호스트가 같음.
https://example.com/user/1 // 실패, 프로토콜이 HTTP, HTTPS로 동일하지 않음
http://notexample.com/user/1 // 실패, 호스트가 example.com, notexample.com으로 동일하지 않음
http://example.com:81/user/1 // 실패, HTTP는 기본 포트가 80이나 여기서 81으로 요청을 해 포트가 동일하지 않음.

CORS란(Cross-Origin-Resource-Sharing)

  • Origin이 다른 곳에서 요청을 보냈을 때, 예외적으로 특정조건을 갖춘 경우 요청을 허용해주는 정책이다. (SOP의 예외상황이라고 보면 된다 => 출처가 달라도 요청을 허용해주는 것.)

  • 보안상의 이유로 SOP가 생겨났다. 하지만, 웹과 브라우저의 발전이 고도화되면서 출처가 다른 곳에서도 데이터를 가져올 필요가 많아졌고, 이를 해결하기 위해 CORS라는 예외정책을 둔 것이라고 생각하면 쉽다.

CORS를 구분하는 로직은 서버가 아닌 브라우저에 구현된 로직이다.

  • 서버는 CORS 정책예외를 구현하도록 도와주는 것 뿐, 결국 출처를 판단하는 것은 브라우저 상에서 이뤄진다.

  • 브라우저는 Http 프로토콜을 이용해 요청을 보냄 > 헤더에 origin이라는 필드를 출처에 담아 보낸다.

  • 서버는 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트로 전달한다.
    (이 리소스를 접근하는 것이 허용된 출처)

  • 이후 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 Access-Control-Allow-Origin을 비교해본 후 차단할지 말지를 결정한다.

  • 만약 유효하지 않다면 그 응답을 사용하지 않고 버린다. (CORS 에러 !!)

CORS를 처리하는 방법?

  • 보통 CORS는 서버쪽에서 handling 하는게 일반적이다.

  • CORS를 판단하는 로직은 브라우저에서 요청에 대한 응답을 받았을 때 이뤄지는데, 이때 헤더에Access-Control-Allow-Origin 값이 존재한다면, CORS에러가 발생하지 않는다.

  • 즉, 서버에서 요청이 온 브라우저의 출처를 Access-Control-Allow-Origin 값에 넣어서 보내주면 해결된다. 아니면 CORS를 처리하는 미들웨어를 사용하는 방법도 존재한다.

  • 하지만 외부 API를 사용하는 경우, 서버쪽의 코드를 수정 할 수 없는 경우들이 있다. 이때는 클라이언트에서 CORS를 처리해야한다.

  • 클라이언트에서는 Proxy 서버를 이용해 CORS를 처리한다.

  • 즉,서버로 요청을 보내기전 중개서버를 통해 출처를 같게 수정하고 서버에 접근하도록 하면 CORS 에러를 해결 할 수 있다.

http-proxy-middleware

  • 구현과제에서 프록시 서버로는 http-proxy-middleware를 사용했다.

  • 먼저 다음과 같이 src폴더안에 setupProxy.js파일을 생성한다.

  • React에서는 setupProxy.js 파일이 있으면 따로 설정을 해주지 않아도 자동으로 반영한다.

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function (app) {
  app.use('/v1',
    createProxyMiddleware({
      target: 'https://api.kakao.com',
      changeOrigin: true,
    }),
  );
};
  • 여기서 /v1은 api의 endpoint이다. 즉 api가 서버에서 리소스에 접근할 수 있도록 가능하게 하는 url이라고 볼 수 있다.

  • 즉, '/v1'으로 시작하는 endpoint를 가진 모든 api를 target으로 주소를 바꿔주는 것이다.

  • target에는 내가 출처를 바꿀 서버의 출처를 적어주면 된다.

  • 여기서 changeOrigin은 호출시 출처를 target값으로 바꿀지를 결정하는 여부이다.

  const fetchData = async () => {
    const datas = await API.get('/v1/music/mylist');
    setMusicInfo(datas);
    setLoading(false);
    console.log(datas);
  };

  useEffect(() => {
    fetchData();
  }, []);

  • 아래 자세히 정리된 글들이 있으니 읽어보길 추천한다.

ref)
CORS : https://inpa.tistory.com/entry/WEB-📚-CORS-💯-정리-해결-방법-👏#CORS_에러_한방_이해하기

https://www.datoybi.com/http-proxy-middleware/

profile
응애 나 애기 개발자

0개의 댓글