똑같은 삽질은 2번 하지 말자

Axios Access-Control-Allow-Origin issue 본문

Javascript

Axios Access-Control-Allow-Origin issue

곽빵 2020. 4. 15. 11:06

Node.js (Server) + Vue.js (Front)

Axios

Promise (비동기 로직 자바스크립트 객체) 기반의 API 통신(HTTP) 라이브러리, Vue에서 권고하는 HTTP 통신 라이브러리는 액시오스(Axios)입니다. 상대적으로 다른 HTTP 통신 라이브러리들에 비해 문서화가 잘되어 있고 API가 다양합니다.

 

npm - axios

 

axios

Promise based HTTP client for the browser and node.js

www.npmjs.com

CORS

CORS란  Cross Origin Resource Sharing의 약자로,

현재 Application의 도메인(웹페이지)에서 다른 웹페이지 도메인으로 리소스가 요청할 때 허용하기 위한 하나의 메커니즘이다.

그렇다는 것은 브라우저는 다른 출처의 리소스를 접근하는 것을 제한하고 있다는 것인가? 라고 한다면 그렇다! 제한하고 있다. 그게 바로 브SOP(Same Origin Policy)라는 정책으로 다른 출처의 리소스를 사용하거나 상호작용을 하지 못하도록 막고, CORS을 사용하지 않고 접근 하려고 하면 Axios Access-Control-Allow-Origin 라는 에러가 발생하는 것이다.

 

예를 들면, 웹페이지인 http://web.com 에서 API서버 URL인 http://api.com 도메인으로 API를 요청하면 브라우저 자체에서 보안 상 이유로 리소스 이용에 제한하는 현상이 SOP로 인해 발생하는 것이다.

SPA(Single Page Application) 기반 앱을 RESTful API 이용하는 방식으로 개발을 하다보면 API 서버와 웹페이지 서버가 각각 따로 운영이 되므로 CORS 문제에 항상 부딪히는 경우가 아주 많아서 잘 알아두도록 하자.

주의점

SOP(Same Origin Policy)라는 메커니즘은 브라우저의 보안을 위한 정책으로 1995년에 출시 되었다. 그럼 그때부터 출처가 다른 브라우저 간의 리소스 공유를 전부 금지? 되어버리는 것은 아니다. 그렇게 되면 이미 잘 되고 있던 브라우저들도 완전히 망가져 버리는 끔찍한 일이 일어나기 때문이다. 그러므로 예외 라는 것이 있다. 그 예외중 한개가 <img src="다른도메인이미지URL" />이 있다. img태그의 경우에는 SOP에 걸리지 않고 이미지를 잘 습득한다. 이렇듯 예외라는 부분이 존재하기 때문에 CORS를 사용해서 리소스에 접근해야 하는지 아닌지 더더욱 헷갈리는 것 같은데 이를 잘 인지해두도록 하자. 그리고 SOP는 브라우저에만 해당이라는 전제가 깔려있는 것도 알아두자.

SOP의 예외 출처:https://ieftimov.com/posts/deep-dive-cors-history-how-it-works-best-practices/#:~:text=The%20same%2Dorigin%20policy%20was,implement%20some%20form%20of%20it.

해결방법

이 문제를 해결하기 위해서는 API 요청을 받는 쪽. 즉, API서버의 응답 헤더를 변경해주는 것으로 

해결 해 줄 수 있습니다. 서버 헤더 중 Access-Control-Allow-Origin이라는 헤더 프로퍼티가 있는데, 

이 헤더는 CORS를 허용해 주는 도메인을 설정해 주는 역할을 합니다.
이렇게 node.js Express기반의 API 서버에서 Access-Control-Allow-Origin 헤더를 

설정해줄 수 있는 cors npm 모듈이 있습니다. 

npm install --save cors
const express = require('express');
const cors = require('cors');

let corsOption = {
    origin: 'http://localhost:8000' // 허락하는 요청 주소
    credentials: true // true하면 프론트에 쿠키를 공유할수있게된다.
} 

app.use(cors(corsOption)); // CORS 미들웨어 추가

여러가지 설정도 추가 할 수 있기때문에 보안적인 이슈도 어느정도 예방할 수 있다.

 

이렇게 corsOption에 요청을 허락할 origin을 추가하는것으로  Access-Control-Allow-Origin이라는 값에 “http://localhost:8080”를 내려주고, 이후 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준

응답의 Access-Control-Allow-Origin을 비교해본 후 이 응답이 유효한 응답인지 아닌지를 판단한다.

 

그리고 유효한 응답의 경우에는 브라우저가 클라이언트 쪽으로 응답을 보내준다.

 

  ↓ 좀더 자세히 알고싶은 분들은 이하의 링크를 참조하시길! (상당히 이해하기 쉽게 잘 설명해 주셨습니다.)

https://evan-moon.github.io/2020/05/21/about-cors/

 

CORS는 왜 이렇게 우리를 힘들게 하는걸까?

이번 포스팅에서는 웹 개발자라면 한번쯤은 얻어맞아 봤을 법한 정책에 대한 이야기를 해보려고 한다. 사실 웹 개발을 하다보면 CORS 정책 위반으로 인해 에러가 발생하는 상황은 굉장히 흔해서

evan-moon.github.io

 

Comments