본문 바로가기
경일/nodejs

[node.js] CORS 해결 방법 (SOP와 CORS)

by dev_kong 2022. 3. 7.
728x90
728x90

0. 목차

1. 개요

2. SOP와 CORS

3. 해결방법

4. CORS 외부 라이브러리

1. 개요

개발자들은 참 신비로운 존재다.

뭘 그렇게 쪼개는걸 참 좋아한다.

그리고 코드가 중복적으로 사용되는걸 겁나 싫어한다.

그리고 이젠 하다하다 서버도 둘로 쪼갠다.

프론트서버랑 백서버

백서버에서는 주로 db와 통신을 하고,

프론트에서는 db와 통신한 데이터를 이용해 화면을 구성한다.

아 그렇구나.. 라고 받아들이기 직전에

..이게 되나?

라는 생각이 든다.

서버가 두개라는 거는 서로다른 포트를 통해 통신을 한다는 건데,

A라는 포트에서 열린서버가

B라는 포트에서 열린서버에 요청을 보내는게 된다고?

당연히 안된다.

근데 되게 만든다.

왜 안되는지와 어떻게 되게하는지에 대한 포스팅이다.

2. SOP와 CORS

실제로 위 처럼 서버를 나누고 작업을 해보면 에러가 발생한다.

음 뭐 그래 CORS 정책에 의해 포트 4001에서 포트 3001 로 열린 서버에 보낸 XMLHttpRequest는 블록되었다고 한다.

(axios로 post 요청 날림)

그렇단다.

자연스레 드는 의문 CORS가 뭘까..

CORS란 Cross Origin Resource Sharing의 약자이다, 직역하자면 Origin(host)를 가로질러 자원에 접근 할 수 있는 권한을 부여하도록 브라우저에 알려주는 정책이다.

와 그렇구나!

그렇다면 위의 에러 메세지가 조금 이해가 된다.

내가 만든 서버는 origin을 가로질러 자원에 접근 할 수 있는 권한에 대한 내용을 브라우저에 알려주지 않았기 때문에(CORS정책 안만듬)

에러가 발생했다.

조금 번거롭다.

왜 막아 놨을까 불편하게...

근데 이것도 조금만 생각해보면 당연한거다.

지금 같은 경우는 두개의 서버 모두 내가 만든거라는 것을 나는 안다.

하지만 컴퓨터는 모른다.

누가만들었는지 알게 뭐람 얘 입장에선 그냥 다른 두개의 서버다.

만약 내가 다른 사람이 만든 서버에 임의로 post요청을 이빠이 날릴 수 있다면?

당연히 보안상 굉장히 취약해질 것이다.

컴퓨터 입장에선 그걸 일단 막고 보는 거다.

그래서 만들어진 rule 이 하나 있다.

그게 바로

SOP 이다

SOP 란 Same Origin Policy 의 약어로

같은 origin(출처) 정책.. .이라는 건데..

같은 origin(출처) 끼리만 요청응답 주고 받을 수 있음! 이런 뜻이다.

근데 위에 CORS도 그렇고 여기도 그렇고

Origin 이 자꾸 등장한다.

...ㅎ Origin에 대해 알아보자

cors에 대해 검색을 하다보면 자주 보이는 이미지 중에 하나다 ㅋㅋ

이때 출처는 Protocol과 Host, 그리고 위 그림에는 나와있지 않지만 :80, :443과 같은 포트 번호까지 모두 합친 것을 의미한다.

즉, 서버의 위치를 찾아가기 위해 필요한 가장 기본적인 것들을 합쳐놓은 것이다.

내가 만든 두개의 서버는 현재

http://localhost:3001

http://localhost:4001 인데

protocol 과 host 는 같지만 포트번호가 다르니

Same Origin이 아니다.

그러니 서로 요청과 응답을 주고 받으려니

SOP 에 어긋난다.

그래서 CORS 정책을 확인해보는데

지정이 안되어있다.

그렇다면 ㅇㅋ 에러 발생!

이 된거다.

3. 해결방법

그러면 이거 어떻게 해결하나여;

res.setHeader 를 통해 cors 정책을 만들어 줄 수 있다.

// 헤더에 작성된 출처만 브라우저가 리소스를 접근할 수 있도록 허용함. 
Access-Control-Allow-Origin: <https://naver.com> 

// 리소스 접근을 허용하는 HTTP 메서드를 지정해 주는 헤더 
Access-Control-Request-Methods: GET, POST, PUT, DELETE 

// 서버에서 응답 헤더에 추가해 줘야 브라우저의 자바스크립트에서 헤더에 접근 허용 
Access-Control-Expose-Headers: Content-type 

// 자바스크립트 요청에서 credentials가 include일 때 요청에 대한 응답을 할 수 있는지를 나타낸다 
Access-Control-Allow-Credentials: true

뭐 이런 애들이 있다..

ㅎ 뭐 대충 봐도 곤란하다.

res.setHeader('Access-Control-Allow-Origin','http://localhost:3001')

이런 식으로 전부 만들어 주면 된다.

내용이 어렵진 않다 다만 귀찮을 뿐..!

나와 같은 생각을 하는 사람이 있어서,

그리고 그 사람이 똑똑한 사람이어서 참 다행이다.

편하게 쓸 수 있는 외부 라이브러리가 있다.ㅎ

4. CORS 외부 라이브러리

사용법은 매우매우 간단하다.

모듈을 설치해주고

$ npm install cors

땡겨오고

const cors = require('cors');

미들웨어 설정을 해주면

app.use(cors())

너무나 쉽고..

그런데 지금 위에 처럼 설정을 해놓으면 세상 모든 서버에서 보내는 요청을 모두 수락하겠다는 건데

이건 좀 문제가 있어보인다.

const corsConfig = {
  origin: 'http://localhost:4001',
  credentials: true,
};

app.use(cors(corsConfig));

이렇게 허용해줄 출처도 정해주고 credentials 에 대한 부분도 정해줘서 옵션으로 넣어주면 된다.

이렇게 해주면..?

에러메세지는 사라지고

response가 잘 출력된다.

아주 좋고~

예제코드는 깃헙에 있음^^

728x90
728x90

댓글