[ JavaScript ] CORS 에러

한대희·2023년 7월 8일
0

JavaScript

목록 보기
22/23

[ SOP ]

  • CORS를 이해하기 전에 먼저 SOP에 대해 알아 보자.
  • SOP는 same origin policy의 약자로 같은 origin끼리만 통신을 허용하는 것을 의미한다.
  • 여기서 Origin이란 url의 구성요소 중에서 proptocol, host, port를 합친 부분을 의미한다.
  • 예를 들어 네이버 스포츠에 들어가 보면 url이
    https://sports.news.naver.com/news?oid=343&aid=0000122713 이렇게 되어 있는 것을 확인할 수 있다.
  • 여기서 https부터 com까지가 Origin이다.(포트번호는 생략이 되어있는 상태이다) Origin만 같다면 그 뒷 부분이 달라도 같은 출처로 인식 된다.

[ SOP가 왜 필요하지? ]

  • 예를들어 우리가 네이버라는 웹 사이트롤 볼 수 있는 이유는 네이버의 서버에서 데이터를 보내 줬기 때문이다. 그런데 만약에 악의적인 누군가가 나인척을 하고 데이터를 요청하여 내 정보를 가져 가면 안되기 때문에 SOP라는 정책이 있는 것이다.

[ CORS? ]

  • CORS는 Cross Origin Resource Sharing의 약자다.
  • 직역 해 보면 "교차 출처 자원 공유"라는 긍정적인 의미이다. 즉, CORS 에러가 발생을 했다는 것은 SOP정책으로 인해 접근할 수 없으니 접근 하고 싶다면 CORS정책을 따르게 만들어라는 의미이다.

[ CORS 에러 동작 원리 ]

  • 먼저 Origin을 비교해서 다른 Origin이면 Cors 에러를 띄우는 주체는 브라우저다.
  • 따라서 브라우저가 어떻게 Cors에러를 발생시키는지 알아 보자.
  • 먼저 첫번째로 클라이언트에서 HTTP 프로토콜을 이용하여 서버에 요청을 보내게 될 것인데, 이때 브라우저는 request 헤더에 현재 Origin을 넣어서 보내게 된다.
  • 요청을 받은 서버는 응답 헤더에 전달받은 Origin을 Access-Control-Allow-Origin이라는 필드에 넣어서 보내 주게 된다.
  • 이렇게 데이터를 전달 받은 브라우저는 자신이 보냈던 Origin과 Access-Control-Allow-Origin에 담긴 Origin을 비교해서 같으면 통과 시키고, 다르면 Cors 에러를 발생시킨다.

[ CORS에러 해결 방법 ]

  • CORS 에러의 해결 방법은 크게 2가지로 볼 수 있다.
  • 첫번째는 서버에서 허용할 Origin을 지정해 주는 방법
  • 두번째는 Proxy 서버를 이용하는 방법이다.

1. 서버에서 CORS 에러 해결

  • 서버에서 Access-Control-Allow-Origin의 헤더에 허용할 Origin을 담아서 응답하면 된다.
// 이렇게 해주면 locoalhost:3000포트에서 온 요청에 대한 응답에 브라우저가 접근할 수 있다.
Access-Control-Allow-Origin : https://localhost:3000

// 접근을 허용할 http 메서드도 지정할 수 있다.
Access-Control-Request-Methods : GET, POST, PUT, DELETE


// 클라이언트 요청에서 쿠키에 담긴 어떤 정보를 함께 보내줘야 한다면, 즉 credentials가 include일 때 요청에 대한 응답을 할 수 있는지를 나타낸다.
Access-Control-Allow-Credentials : true
  • node.js를 예로 들면 아래와 같다.
const Server = http.createServer((req, res) => {
   //😀 허용할 HTTP 메서드 지정
    response.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE'); 
   //😀 허용할 Origin 지정 
    response.setHeader('Access-Control-Allow-origin', 'https://localhost:3000'); 
   //😀 클라이언트와 서버 간에 쿠키 주고받기 허용
    response.setHeader('Access-Control-Allow-Credentials', 'true'); 
   //😀 상태 코드 보내기
    response.writeHead(200, { 'Content-Type': 'text/plain' });
    response.end('ok');
});

2. Proxy 서버 이용 하기

  • CORS 에러는 브라우저에서 response를 차단 하여 발생하는 오류 이기 때문에, 서버와 서버사이의 요청과 응답에 대해서는 발생하지 않는다.
  • 따라서 클라이언트, 즉 브라우저와 도메인이 같은 Proxy서버를 만들어서 브라우저는 Proxy서버에 Api요청을 하고 프록시 서버가 Api서버에 다시 요청을 하여 데이터를 받아 온 후 브라우저에 보내주는 방식이다.

2-1 package.json 파일에 proxy 설정

  • cra로 만들어진 프로젝트 폴더의 package.json 파일에 proxy속성을 추가하고 여기에 api를 요청할 서버의 origin을 입력해 주면 된다.
  • 그리고 클라이언트에서 get이나 post요청을 할 때는 endpoint만 작성하면 된다.
"proxy": "http://localhost:4000"

2-2 http-proxy-middleware

  • 프록시 서버를 직접 구현하기 어렵 다면 http-proxy-middleware를 사용하여 익스프레스와 쉽게 연동할 수 있다.
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
  //😀 어떤 endpoint의 요청에 대해 proxy할지 입력해 준다.
    '/api',
    createProxyMiddleware({
    //😀 target에 Api서버의 Origin을 입력해 준다.
      target: 'http://localhost:5000',
      changeOrigin: true,
    })
  );
};
profile
개발 블로그

0개의 댓글

관련 채용 정보