cors


cors란?

cors란 Cross-Origin Resource Sharing의 줄임말인데, 추가적인 HTTP Header를 사용해 애플리케이션이 다른 origin의 리소스에 접근할 수 있도록 하는 메커니즘을 말한다. 동시에 다른 origin에서 내 리소스에 함부로 접근하지 못하게 하기 위해 사용된다. 만약 내가 서비스하지 않는 사이트에서 세션을 요청해서 획득한다면 악의적으로 내 세션을 탈취해 다른 행동을 취할 수 있다. 그래서 브라우저에서는 이러한 요청을 막고, 내가 허용한 origin들만 요청할 수 있도록 하기 위해 필요하다.

cors는 브라우저에서 발생하는 것이기 때문에, 서버에서 통신 시 이러한 정책이 적용되지 않는다.

cors는 브라우저가 리소스를 요청할 때 추가적인 정보를 header에 담는다. 내 origin은 무엇이고 어떤 메소드를 사용해서 요청을 할 것이고 어떤 header들을 포함할 것인지 담아서 서버에 전송한다.


cors 해결하기

1.script의 src 속성을 통해 API, 데이터 요청

  <script type="text/javascript"
    src="//dapi.kakao.com/v2/maps/sdk.js?appkey=앱 키?&libraries=services,clusterer,drawing"></script>

나같은 경우, 프로젝트를 진행할 때 script로 API를 불러와 사용했기 때문에 cors의 정책에서 벗어날 수 있었다. script 태그의 src 속성값엔 도메인 제약이 없기 떄문이다. 위의 형태로 depi.kakao.com에 데이터를 요청하면 JSONP(JSON with padding)이라 불리는 프로토콜을 사용해 데이터를 가져온다. 이 방식은 오래된 브라우저도 지원한다.

2.cors 라이브러리 사용하기

    npm install --save-dev cors

cors 라이브러리가 따로 있기 떄문에 이를 이용해 편리하게 해결할 수 있다.

    const cors = require('cors');

    app.use(cors());

app.use(cors()); 로 설정하면 모든 cross-origin에 대해 응답을 해준다. 하지만 이러한 방식은 보안에 취약할 수 있으므로 주의해야한다. 보안상 특정 도메인 이나 특정 요청에만 응답하는 경우는 그에 따른 옵션들을 다양하게 설정해줄 수 있다.

특정 도메인 허용

const corsOptions = {
  origin: 'http://example.com', // 접근 권한을 부여하는 도메인
  credentials: true, // 응답 헤더에 Access-Control-Allow-Credentials 추가해줌
  optionsSuccessStatus: 200 // 응답 상태 200으로 설정 
};

app.use(cors(corsOptions));

특정 요청 접근 허용

app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
});

3. Access-Control-Allow-Origin 세팅

app.get("/api/keywords", (req, res) => {
  res.header("Access-Control-Allow-Origin", "*") // 헤더를 추가한다
  res.json(keywords)
})

이는 서버측 솔루션으로, header에 Access-Control-Allow-Origin의 값을 수정하여 응답할 도메인이나 요청을 위의 cors 라이브러리에서 했던 방식대로 설정해줄 수 있다.

4. Webpack Dev Server로 리버스 프록싱하기

// webpack.config.js
module.exports = {
  devServer: {
    proxy: {
      "/api": "http://localhost:8081", // 프록시
    },
  },
}

웹팩 설정파일인 webpack.config.js에서 devServer 모듈에서 프록시 설정을 해주면 된다. 개발서버에 들어온 모든 HTTP 요청중 /api로 시작되는 것은 http://localhost:8081로 요청하는 설정이다. 브라우저에서 API를 요청 하는 것이 아닌 Webpack Devserver를 통해 API를 요청하는 것이기 떄문에 cors의 제한을 받지 않는다.


Reference

https://velog.io/@hwang-eunji/CORS
https://ko.javascript.info/fetch-crossorigin
https://evan-moon.github.io/2020/05/21/about-cors/
https://jeonghwan-kim.github.io/series/2020/01/02/frontend-dev-env-webpack-intermediate.html

You might also enjoy