본문 바로가기

카테고리 없음

cors

CORS 에러란?

Cross-Origin Resource Sharing의 약어이다. 한국어로는 교차 출처 리소스 공유이며, 다른 출처(Origin)로 리소스를 요청하는 방식을 일컫는다.

CORS는 최신 브라우저의 동일 출처 정책(Same-Origin Policy) 때문에 등장하게 되었으며, 다른 출처일 때도 리소스를 공유하기 위해 프론트와 백엔드는 별도의 설정을 해주어야 한다.

CORS 에러는 언제 발생할까?

다른 출처(Origin)로 리소스를 요청할 때 발생한다.

URL 구조에서 프로토콜과 호스트가 모든 같은 것을 동일 출처라고 한다. 프로토콜, 도메인, 포트번호 중 하나라도 다르면 다른 출처이다.

이전에는 동일한 도메인에서 리소스를 받아왔는데, 지금은 클라이언트에서 다른 서버(ex. Backend, Oauth)로 리소스를 요청하는 경우가 많이 생겼다.

즉 다른 출처로 리소스를 요청하는 경우이므로 CORS 에러가 발생한다.

CORS 동작방식

웹에서 다른 출처로 리소스를 요청할 때 자동적으로 요청 헤더의 Origin에 출처를 담아서 보낸다.

- 요청 헤더

Origin: https://verilog.io

 

다른 출처에서 웹에 리소스를 제공할 때 응답 헤더의 Access-Control-Allow-Origin에 허용할 출처를 담아서 응답한다.

- 응답 헤더

Access-Control-Allow-Origin: https://verilog.io

 

웹에서 응답을 처리할 때 자신이 보낸 Origin과 응답 헤더의 Access-control-Allow-Origin과 비교하여 이 응답이 유효하면 응답을 허용한다.

다를 경우에 이 응답을 버리고 CORS 에러를 발생시킨다.

https://verilog.io는 같으므로 응답을 허용한다.

 

 

모든 출처에 대해 환영

응답 헤더의 Access-Control-Allow-Origin: * 로 모든 출처를 허용하면 모든 응답을 허용하므로, 당장은 편할 수 있지만 보안상 심각한 이슈가 생길 수 있으므로 사용하지 않는 것이 좋다.

따라서 웹에서 다른 서버로 요청할 때 CORS 에러가 생기지 않도록 적절한 해결방법을 선택해야 한다.

백엔드쪽에서 해결하는 방법

가장 정석적인 방법으로 백엔드에서 Access-Control-Allow-Origin을 프론트의 요청헤더인 Origin과 같은 출처로 설정하면 된다.

1. 직접 헤더에 명시

res.setHeader('Access-Control-Allow-origin', '*'); // CORS 허용
res.setHeader('Access-Control-Allow-Credentials', 'true'); // 쿠키 주고받기 허용

res.end();

출처: https://inpa.tistory.com/entry/NODE-📚-CORS-설정하기-cors-모듈 [Inpa Dev 👨‍💻:티스토리]

2. Express의 cors 미들웨어 사용

var express = require('express');
var cors = require('cors');
var app = express();

app.use(cors({
    origin: * // CORS 허용
    credential: true // 사용자 인증이 필요한 리소스(쿠키 ..등) 접근
}));

출처: https://inpa.tistory.com/entry/NODE-📚-CORS-설정하기-cors-모듈 [Inpa Dev 👨‍💻:티스토리]

프론트엔드에서 해결하는 방법

정석적인 방법은 아니지만 프론트엔드에서도 해결할 수 있는 방법이 있다.

 

1. 남이 만든 프록시 서버 사용하기

프록시 서버는 클라이언트가 프록시 서버를 통해 다른 서버에 접속할 수 있도록 해준다.

다시 말해 브라우저와 다른 서버 간의 통신을 중계하는 서버이다.

https://cors-anywhere.herokuapp.com
axios({
    method: "GET",
    url: `https://cors-anywhere.herokuapp.com/https://api.domain.com`,
    headers: {
    'APIKey': ${your_API_key},
},

url에 프록시 서버/{url}로 요청하면 CORS를 해결할 수 있다.

 

2. http-proxy-middleware

리액트에서 배포하기전 로컬 한정일 때 사용하면 좋은 라이브러리이다. (vite는 다른 방법이 있습니다!)

1. npm i http-proxy-middleware 으로 설치한다.

 

2. src/setupProxy.js 파일 생성 및 작성

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

const app = express();

app.use(
  '/api',
  createProxyMiddleware({
    target: 'http://api.domain.com',
    changeOrigin: true,
  }),
);

app.listen(3000);

 

로컬 환경에서 http://localhost:3000/api로 시작되는요청을 라이브러리가 http://www.api.domain.com/api로 Origin을 변경하여 CORS 문제를 해결할 수 있다.

이때 createProxyMiddleware의 옵션을 지정할 수 있다.

- target : 리소스를 요청할 서버의 출처

- changeOrigin : target url로 origin의 출처를 변경할 것인지 여부를 나타내며 기본값은 false이다.

 

 

출처

https://bohyeon-n.github.io/deploy/web/cors.html

https://velog.io/@jh100m1/CORS-%EC%97%90%EB%9F%AC%EA%B0%80-%EB%AD%94%EB%8D%B0-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%95%B4%EA%B2%B0%ED%95%98%EB%8A%94%EA%B1%B4%EB%8D%B0

https://coding-maggot.tistory.com/100