CORS는 어떻게 해결할 수 있을까?


:raising_hand: 프론트엔드 개발관련 공부내용을 기록하는 포스트 입니다.


image

1. 개요


3번의 CORS 포스팅의 마지막이다.

이제 최종적으로 “우리는 CORS를 어떻게 해결하면 될까?” 에 대해서 작성해 보려 한다.

CORS는 굉장히 자주 들었지만, 그때마다 대충대충 찾아보고 “아..이런거구나” 하며 넘어갔던 경우가 굉장히 많다.

이렇게 실제로 정확히 분석해가면서 이해하는 과정이 무조건 필요한 개념인것 같다.

그럼 마지막 포스팅 또한 evan-moon님의 블로그를 참고하여 본인이 이해한 내용들을 차근차근 작성해 보도록 한다.

2. CORS 문제를 해결하는 방법


이전 포스팅에서 CORS가 무엇인지 그리고 어떻게 동작하는지에 대해서 확인하였다.

이번엔 어떻게 해결할 수 있을 지 확인해보자.

2-1. Access-Control-Allow-Origin 설정

앞선 포스팅에서도 확인 할 수 있듯이, CORS에서 가장 중요한 요건은 Access-Control-Allow-Origin 와의 규칙 확인 즉, 출처(Origin)의 정책을 잘 지켜서 호출하고 응답하는 부분 일 것 같다.

이 정책은 Front 보다는 BackEnd 측에서 Access-Control-Allow-Origin 값을 *로 설정해주는 방법이 있다.

하지만, Access-Control-Allow-Origin*로 설정할 경우 Request에 명시되어 있는 출처가 어디든지 모든 요청에 대해서 정상으로 간주하고 응답을 할 것이다.

이렇게 되면 당연하게 보안 이슈가 발생할 것이다.

따라서, *로 설정하기 보다는 정확한 출처(Origin)를 명시해 주는것이 좋을 것이다.

해당 설정은 Nginx 혹은 Apache와 같은 서버 엔진에서 설정을 추가하거나, 미들웨어 소스 코드 내에서 셋팅을 하게 된다.

현재 운영하고 있는 실무 시스템에서는 Gateway ServerCORS에 대한 설정은 진행하였고, Client에서 GET, POST 등의 REST API Call 에 대해서 CORS 적용하고 있다.

2-2. Webpack Dev Server 로 리버스 프록싱

프론트 프로젝트를 진행할때 Vue 가되었든, React 가 되었든 이제는 필수가 된 모듈 번들러 즉, Webapck을 활용해서 손쉽게 개발환경을 구축할 수 있다.

이때, 우리가 localhost 에서 다른 출처의 리소스를 가져오려면 당연히 CORS 에 대한 정책을 위반하게 될 것이다.

이러한 상황에서 Webpack-dev-server의 설정을 통해 손쉽게 우회 할 수 있다.

module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'https://api.jjou33.com,
        changeOrigin: true,
        pathRewrite: { '^/api': '' },
      },
    }
  }
}

해당 설정을 통해 아래와 같은 과정으로 우회가 가능하다.

  1. 클라이언트https://localhost:XXX 와 같은 출처로 서버에 리소스를 요청한다.
  2. Webpackapi로 시작되는 리소스 요청에 대해서 target으로 설정한 출처로 호출을 우회한다.

결과적으로 브라우저https://localhost:XXX로 요청을 보낸것으로 알고 있지만, 실제로 Webpack 설정을 통해서 뒤에서 https://api.jjou33.com 으로 요청을 프록싱 해준다.

따라서, 브라우저는 CORS정책을 지킨것으로 생각하고 자유롭게 서버와 통신을 할 수 있다.

이러한 방법은 실제 프로덕션 환경에서도 클라이언트 어플리케이션의 소스 출처와 API서버의 출처가 같은 경우에 사용하는 것이 좋다.

Webpack모듈 번들러의 기능을 할뿐 실제 빌드 후 운영 배포를 진행하게 되면 더이상 webpack-dev-server가 구동되는 환경이 아니기 때문이다.

즉 예를들면 위에서 예를 든것은 https://localhost:XXX 를 호출하고 webpack-dev-serverhttps://api.jjou33.com으로 우회하는 방식으로 개발에서는 잘 진행될 것이다.

하지만, 운영에서는 https://api.jjou33.com이 아닌 https://www.jjou33.com/api/XX 를 호출하게 되면 출처가 안맞는 부분도 있겠지만, 운영환경에서는 프록싱 로직이 없기 때문에 404 Not Found를 만날 수도 있다.

Node로 개발했을 경우 비지니스 로직 내에서 process.env.NODE_ENV 로 빌드 환경 변수를 사용하여 분기 로직을 작성할 수도 있긴하지만, 좋은 방법은 아니다.

3. CORS 포스팅을 마치며


이번 CORS에 대한 포스팅은 어떻게 보면 특정 블로그에 대한 내용을 많이 참고해서 작성한 경우이다.

이 블로그에 포스팅을 작성하는 이유는 하나다.

내 기억력을 못믿는다. 이 이유 하나만으로 언젠가부터 내가 공부하는 모든것을 내 스스로가 이해한 방식대로 포스팅을 진행하고 있다.

학습을 해도 몇일 지나면 기억이 잘안나고 또 여러가지 리소스를 활용하여 내 머리속에 있는 특정 개념 혹은 기술에 대한 그림을 그리는 것 또한 기술을 체득하는데 큰 도움이 되는것 같다.

이번 포스팅은 우연히 좋은 블로그를 정독하다가 글이 너무 좋고 이해가 잘 되서 많은 참고를 하였다.

아직도 공부할게 항상 많고, 늘 하나하나씩 채워나가며 배움을 즐기고 싶다.

참조 사이트