Home CORS 오류 해결방법
Post
X

CORS 오류 해결방법

발생 오류

Access to XMLHttpRequest at 'http://localhost:5000/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

‘http://localhost:5000/’에서 ‘http://localhost:3000’ 출처로 가져올 수 있는 액세스가 CORS 정책에 의해 차단되었습니다. 요청된 리소스에 Access-Control-Allow-Origin’ 헤더가 없습니다. 불투명한 응답이 필요에 적합한 경우, 요청 모드를 ‘no-cors’로 설정하여 CORS가 비활성화된 리소스를 가져오십시오.

AxiosError {message: ‘Network Error’, name: ‘AxiosError’, code: ‘ERR_NETWORK’, config: {…}, request: XMLHttpRequest, …}

React (Client)에서 Express (Server)로 데이터를 요청하는 과정에서 에러가 발생했습니다.

보통 Axios의 Network Error는 다음과 같은 원인으로 발생합니다.

  1. 네트워크 연결 불안정
  2. 잘못된 엔드포인트 요청 또는 설정
  3. Cross-Origin Resource Sharing (CORS) 문제

postman으로 동일한 요청을 했더니 정상적으로 응답이 오는 것을 확인할 수 있었습니다.

또한, 크롬 개발자 도구의 Network를 확인하면 CORS 문제로 오류가 발생한 것을 알 수 있습니다.

react-cors

발생한 오류를 해결하기위해 먼저 SOPCORS에 대해 알아보겠습니다.


SOP (Same-Origin Policy)

SOP (Same-Origin Policy) 는 웹에서 다른 출처로의 리소스 요청을 제한하는 정책 중 하나로, 같은 출처의 리소스만 공유할 수 있도록 제한하는 정책입니다.

  • 같은 출처

    same-origin

    같은 출처란 URL에서 Protocol, Host, Port가 같다는 의미입니다.


SOP 필요성

인터넷상의 악의적인 사이트들의 공격들과 잠재적으로 해로울 수 있는 문서를 격리해 보안 위협으로부터 보호합니다.

예를 들면, 오늘날 많은 웹 사이트들은 로그인 서비스를 제공할 때 대부분 Token이나 Session을 활용합니다.

발급받은 Token과 같은 정보들은 브라우저에 저장되어 해당 사이트로 요청을 보낼 때마다 함께 보내지게 됩니다.

만약 SOP가 없는 경우, XSS, CSRF 등의 방식으로 정보를 탈취 하거나, 사용자 모르게 요청을 보내는 등의 해킹에 취약해집니다.

참고 글 : XSS, CSRF

즉, 서로 다른 사이트로부터 리소스 교환을 막아 위험을 제거하는 것입니다.


그렇다면 SOP에 따른 다른 출처로부터의 리소스 제한은 정답일까요?

웹 생태계가 다양해지면서 여러 서비스들끼리 데이터를 주고받을 필요성이 생겼습니다.

따라서, 기본적으로 SOP로 인해 다른 출처로부터 리소스를 가져올 수 없지만 어떤 기준을 충족시키면 리소스 교환이 가능하도록 CORS (Cross-Origin Resource Sharing)를 활용합니다.


CORS (Cross-Origin Resource Sharing)

한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제 (출처 : MDN)

즉, CORS (Cross-Origin Resource Sharing)는 다른 출처로부터의 데이터 교환을 선택적으로 허용하는 방법입니다.


CORS 동작 원리

  1. Client가 요청 헤더의 Origin에 본인 출처를 담아서 Server로 리소스를 요청합니다.

  2. Server는 응답 헤더의 Access-Control-Allow-Origin에 허용되는 출처를 담아서 응답합니다.

  3. Client는 OriginAccess-Control-Allow-Origin을 비교합니다.

  4. 일치하면 그대로 응답을 사용하고, 다르다면 에러를 출력하고 응답을 버립니다.


React (Client) 에서 CORS 에러 해결하기

Proxy 서버를 사용하여 CORS 문제를 해결해보겠습니다.

  • CRA (create-react-app)을 사용한 경우

    package.json 파일에 ‘proxy’ : ‘허용할 주소’를 적는 것으로 해결할 수 있습니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    {
      {
    
      ...
    
      "development": [
        "last 1 chrome version",
        "last 1 firefox version",
        "last 1 safari version"
      ]
      },
      "proxy": "http://localhost:5000"
    }
    
  • CRA를 사용하지 않은 경우

    http-proxy-middleware 모듈로 구현할 수 있습니다.

    참고 글 : React 공식 문서


Express (Server) 에서 CORS 에러 해결하기

cors 모듈을 활용해 CORS 문제를 해결해보겠습니다.

  • 설치
1
2
3
npm i cors

  • 코드 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import express from "express";
import bodyParser from "body-parser";
import cors from "cors";

const app = express();

// Middleware
app.use(
  cors({
    origin: "http://localhost:3000", // 출처 허용 옵션, 모든 출처 허용 (true)
    credential: true, // 사용자 인증이 필요한 리소스(쿠키 ..등) 접근
  })
);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// router
app.get("/", function (req, res) {
  res.send("Hello World");
});

app.listen(5000, () => {
  console.log("Server On");
});
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.