📋CS/네트워크 이론

Cors와 Proxy

하얀성 2024. 6. 6. 11:14

핵심 내용. Cors

  1. 동일 출처 정책 (Same-Origin Policy): 웹 브라우저 보안 정책으로, 웹 페이지가 자신이 로드된 도메인과 다른 도메인으로 요청을 보낼 때 이를 제한합니다. 동일 출처는 프로토콜(http/https), 호스트(도메인), 그리고 포트가 모두 동일한 경우를 말합니다.
  2. CORS 헤더: 서버가 CORS 요청을 허용하기 위해서는 응답 헤더에 Access-Control-Allow-Origin을 설정해야 합니다. 예를 들어, Access-Control-Allow-Origin: * 또는 Access-Control-Allow-Origin: http://example.com 같은 헤더를 설정하면 해당 출처에서의 요청을 허용합니다.

요약:

상대경로란, 상대경로에 맞춰서 내 도메인을 바꿔보낸다는 것. 그것을 proxy 서버에서 해준다.

cors 헤더에 허용 내용을 설정하지 않았다면,  proxy 서버를 통해서 대리접근(상대경로 접근) 해야한다.


 

이미지를 적절한 코드에서 불러오려 하는데 계속 오류가 없는데도 막힘

Q. 콘솔에 에러가 있는가? ㅡ> x

Q. 이미지를 아예전송받지 못했는가? ㅡ> x (깨진 이미지 이모티콘이 있으니 전송은 받은 것 같은데...)

// src/App.js
import React, { useEffect, useState } from "react";
import "./App.css";

function App() {
  const [imageUrl, setImageUrl] = useState("");

  useEffect(() => {
    const calculateSimpleCurTime = () => {
      const now = new Date();
      const simpleCurTime =
        now.getUTCFullYear().toString().slice(2) +
        ("0" + (now.getUTCMonth() + 1)).slice(-2) +
        ("0" + now.getUTCDate()).slice(-2) +
        ("0" + now.getUTCHours()).slice(-2) +
        ("0" + now.getUTCMinutes()).slice(-2);

      let simpleCurTimeInt = parseInt(simpleCurTime);

      if (parseInt(("0" + now.getUTCHours()).slice(-2)) === 0) {
        if (parseInt(("0" + now.getUTCMinutes()).slice(-2)) < 4) {
          simpleCurTimeInt += 2400;
        }
      }

      if (parseInt(("0" + now.getUTCMinutes()).slice(-2)) < 4) {
        simpleCurTimeInt -= 40;
      }

      if (simpleCurTimeInt % 2 === 1) {
        simpleCurTimeInt -= 1;
      }

      simpleCurTimeInt -= 4;

      return simpleCurTimeInt;
    };

    const simpleCurTime = calculateSimpleCurTime();
    const filename = `k2a_ami_le1b_true+ir_ko020lc_20${simpleCurTime}.thn.png`;
    console.log("Generated filename:", filename); // 파일 이름을 콘솔에 출력
    const imageUrl = `http://kyunsan.iptime.org:8001/img/${filename}`;
    setImageUrl(imageUrl);
  }, []);

  return (
    <div className="App">
      <h1>동적 이미지 로드 (UTC 기준)</h1>
      {imageUrl ? (
        <img
          src={imageUrl}
          alt="동적 로드된 이미지"
          className="dynamic-image"
        />
      ) : (
        <p>로딩 중...</p>
      )}
    </div>
  );
}

export default App;

프록시 설정이 작동하는 이유

create-react-app에서는 개발 중에만 유효한 프록시 설정을 통해 CORS 문제를 해결할 수 있습니다. 이 설정을 사용하면 클라이언트 측 코드에서 서버로 요청을 보낼 때, 요청을 프록시 서버를 통해 전달합니다. 이 과정에서 브라우저가 클라이언트와 서버 간의 도메인이 다르더라도 CORS 문제가 발생하지 않습니다.

작동 원리

  1. 프록시 설정:
    • create-react-app의 package.json 파일에 프록시 설정을 추가합니다.
    • 예: "proxy": "http://kyunsan.iptime.org:8001"
    • 이 설정은 개발 서버가 시작될 때 활성화됩니다.
  2. 상대 경로 사용:
    • 클라이언트 측 코드에서 API 요청을 보낼 때 절대 경로 대신 상대 경로를 사용합니다.
    • 예: /img/... 대신 /img/...
  3. 프록시 서버의 역할:
    • 클라이언트가 상대 경로로 요청을 보낼 때, 개발 서버는 이 요청을 프록시 설정에 따라 http://kyunsan.iptime.org:8001로 전달합니다.
    • 클라이언트 입장에서는 동일한 도메인으로 요청을 보내는 것처럼 보입니다.

이전 방법이 작동하지 않은 이유

이전 방법에서는 클라이언트가 직접 http://kyunsan.iptime.org:8001/img/...로 요청을 보냈습니다. 이 경우 다음과 같은 문제가 발생합니다:

  1. CORS 정책:
    • 브라우저는 클라이언트가 다른 도메인으로 요청을 보낼 때, 서버가 Access-Control-Allow-Origin 헤더를 설정하지 않았다면 요청을 차단합니다.
    • 이는 보안 상의 이유로 동일 출처 정책(Same-Origin Policy)에 의해 발생합니다.
  2. 절대 경로 사용:
    • 클라이언트가 절대 경로를 사용하여 요청을 보낼 때, 브라우저는 요청이 다른 도메인으로 향하는 것을 인식하고 CORS 정책을 적용합니다.
    • 서버에서 적절한 CORS 헤더를 설정하지 않았다면, 요청은 차단됩니다.

작동 과정 요약

  1. 프록시 설정 추가: package.json 파일에 "proxy": "http://kyunsan.iptime.org:8001" 설정을 추가합니다.
  2. 상대 경로 사용: 클라이언트 코드에서 API 요청을 보낼 때 절대 경로 대신 상대 경로를 사용합니다.
  3. 요청 전달: 개발 서버는 클라이언트로부터 받은 상대 경로 요청을 프록시 설정에 따라 지정된 서버(http://kyunsan.iptime.org:8001)로 전달합니다.
  4. CORS 문제 해결: 클라이언트 입장에서는 동일한 도메인으로 요청을 보내는 것처럼 보이므로, 브라우저의 CORS 정책이 문제가 되지 않습니다.
  5.  

문제 해결 및 코드 비교 

 

절대 경로 사용 (CORS 문제 발생):

const imageUrl = `http://kyunsan.iptime.org:8001/img/${filename}`;
setImageUrl(imageUrl);

 

상대 경로 사용 (프록시 통해 CORS 문제 해결):

const imageUrl = `/img/${filename}`;
setImageUrl(imageUrl);

 

 

package.json에 proxy 등록.

{
  "name": "your-app-name",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    // ... your dependencies
  },
  "scripts": {
    // ... your scripts
  },
  "proxy": "http://kyunsan.iptime.org:8001"
}

Cors란?

 

웹 페이지와 도메인

  1. 도메인: 웹 페이지가 로드되는 웹 주소입니다. 예를 들어, http://example.com은 하나의 도메인입니다.
  2. 동일 출처 정책 (Same-Origin Policy): 웹 브라우저 보안 정책으로, 웹 페이지가 자신이 로드된 도메인과 다른 도메인으로 요청을 보낼 때 이를 제한합니다. 동일 출처는 프로토콜(http/https), 호스트(도메인), 그리고 포트가 모두 동일한 경우를 말합니다.

예제 시나리오

절대 경로와 상대 경로

전체 과정 설명

1. 웹 페이지 로드

  • 클라이언트: 웹 페이지를 로드합니다. 여기서 클라이언트는 브라우저에서 http://localhost:3000에서 로드된 React 앱입니다.
  • 도메인: http://localhost:3000 (React 개발 서버의 도메인)

2. 이미지 요청

  1. 절대 경로로 요청:
    • 클라이언트가 http://kyunsan.iptime.org:8001/img/filename.png로 요청을 보냅니다.
    • 다른 도메인: 요청을 보내는 도메인(http://localhost:3000)과 요청을 받는 도메인(http://kyunsan.iptime.org:8001)이 다릅니다.
    • CORS 문제: 브라우저는 다른 도메인으로의 요청을 보안상 이유로 제한합니다. 서버가 적절한 CORS 헤더를 설정하지 않았다면, 브라우저는 이 요청을 차단합니다.
  2. 상대 경로로 요청:
    • 클라이언트가 /img/filename.png로 요청을 보냅니다.
    • 같은 도메인처럼 보임: 브라우저는 이 요청을 현재 로드된 도메인(http://localhost:3000)으로 보냅니다.
    • 프록시 설정: React 개발 서버는 package.json에 설정된 프록시(http://kyunsan.iptime.org:8001)를 통해 이 요청을 실제 서버로 전달합니다.
    • 브라우저 시각: 클라이언트는 동일한 도메인에서 요청을 보낸 것처럼 보입니다. 따라서 CORS 문제가 발생하지 않습니다.

요약:

상대경로란, 상대경로에 맞춰서 내 도메인을 바꿔보낸다는 것. 그것을 proxy 서버에서 해준다.

아래처럼 cors 헤더에 허용 내용을 설정하지 않았다면, 위와 같이 proxy 서버를 통해서 대리접근(상대경로 접근) 한다.

 

 

CORS 헤더: 서버가 CORS 요청을 허용하기 위해서는 응답 헤더에 Access-Control-Allow-Origin을 설정해야 합니다. 예를 들어, Access-Control-Allow-Origin: * 또는 Access-Control-Allow-Origin: http://example.com 같은 헤더를 설정하면 해당 출처에서의 요청을 허용합니다.

 


출력 결과