상세 컨텐츠

본문 제목

React CORS 설정 - 프록시 (http-proxy-middleware)

Front/React

by Chan.94 2025. 1. 31. 20:28

본문

반응형

CORS란

웹 브라우저에서는 보안상의 이유로, 다른 출처(origin)에서 자원을 요청하는 경우 제한한다.

이것을 **SOP(Same Origin Policy)** 동일 출처 정책이라 한다.

 

즉, 동일 출처(Same-Origin) 서버에 있는 리소스는 자유로이 가져올 수 있지만, 다른 출처(Cross-Origin) 서버의 리소스는 상호작용이 불가능하다는 말이다.


Cross-Origin Resource Sharing

직역하면 "교차 출처 리소스 공유 정책"이라고 해석할 수 있는데, 여기서 교차 출처라고 하는 것은 (엇갈린) 다른 출처를 의미하는 것으로 보면 된다.
’서로 다른 출처에서 리소스를 공유하는 것’을 뜻한다.

 

출처(Origin) 란?

출처(Origin)라는 것은 Protolcol과 Host 그리고 Port까지 모두 합친 URL을 의미한다

여기서 출처는 http://localhost:8080/ 과 같이 프로토콜 + 호스트 + 포트를 말한다. 여기서 하나라도 다르면 출처가 다르다고 말할 수 있다.

예를 들어, React의 3000포트에서 Spring Boot의 8080 포트로 API를 호출할 때, 별다른 설정을 하지 않았다면 출처가 다르므로 CORS 에러가 발생한다.


브라우저의 CORS 기본 동작

1) 클라이언트에서 HTTP요청의 헤더에 Origin을 담아 전달
기본적으로 웹은 HTTP 프로토콜을 이용하여 서버에 요청을 보내게 되는데, 이때 브라우저는 요청 헤더에 Origin 이라는 필드에 출처를 함께 담아 보내게 된다.

 

2) 서버는 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트로 전달

이후 서버가 이 요청에 대한 응답을 할 때 응답 헤더에 Access-Control-Allow-Origin이라는 필드를 추가하고 값으로 '이 리소스를 접근하는 것이 허용된 출처 url’을 내려보낸다.

 

3) 클라이언트에서 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교

  • 브라우저는 Request의 Origin과 Response의 Access-Control-Allow-Origin을 비교해 본 후 차단할지 말지를 결정한다.
  • 만약 유효하지 않다면 그 응답을 사용하지 않는다 (CORS Error)
  • 위의 경우에는 둘다 http://localhost:3000이기 때문에 유효하니 다른 출처의 리소스를 문제없이 가져오게 된다.
결국 CORS 해결책은 서버의 허용이 필요하다.

서버에서 Access-Control-Allow-Origin 헤더에 허용할 출처를 기재해서 클라이언트에 응답하면 되는 것이다.

프록시 서버 사용하기

프록시 서버를 사용하면, Front에서 Back으로 요청을 프록시가 처리하여 브라우저가 같은 출처에서 통신하는 것처럼 보이게 할 수 있다.

 

프록시 서버는 클라이언트가 프록시 서버를 통해 다른 네트워크에 간접적으로 접속할 수 있게 해 준다. 
쉽게 이해하자면 "중계서버"라고 이해하면 된다


http-proxy-middleware 적용

  • http-proxy-middleware 라이브러리 설치
npm install --save http-proxy-middleware
  • setupProxy.js 생성
    src/setupProxy.js 경로에 생성한다.
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app){
    app.use(
        '/main-dev',    // 프록시를 적용할 경로
        createProxyMiddleware( {
            target: 'http://localhost:28081', // 요청이 전달될 백엔드 서버의 URL
            changeOrigin: true,
        })
    );
};

'/main-dev'로 요청을 보내면 실제로는 http://localhost:28081의 백엔드 서버로 전달되게 된다.

포트주소는 각자 상황에 맞도록 설정한다.

  • App.js
import logo from './logo.svg';
import React, {useState, useEffect} from 'react';
import './App.css';

function App() {

  const [message, setMessage] = useState("");

  useEffect( () => {
        fetch('/main-dev/devlog/jpa/selectUserAll', {method : "POST"})
        .then(response => response.json())
        .then(response => {
          console.log(response);
          setMessage(response.data[2].email);
        });
  },[])

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          {message}
        </p>
      </header>
    </div>
  );
}

export default App;

 

useState, useEffect는 React Hook이라는 개념인데 이후 포스팅에서 따로 정리하도록 하겠다.

이번글에서는 프록시를 설정하여 CORS 이슈를 해결하는 것에 집중해 보자.

 

  • SpringSecurity
public class SecurityConfig {
    protected SecurityFilterChain configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
            ...
            .cors(corsConfigurer -> corsConfigurer.configurationSource(corsConfigurationSource()))
            ...
    }
    
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();

        configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000", "http://127.0.0.1:3000")); // 허용할 도메인
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 허용할 HTTP 메서드
        configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type")); // 허용할 헤더
        
        //클라이언트가 CORS 요청에 인증 정보를 포함하도록 허용 - Ex) 쿠키를 전송하거나 인증 헤더(Authorization)를 포함할 수 있음
        configuration.setAllowCredentials(true); 

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration); // 모든 경로에 CORS 정책 적용

        return source;
    }
}

React (프론트엔드)에서 오는 요청만을 허용하고, 특정 HTTP 메서드와 헤더를 사용할 수 있도록 한다.

이는 보안을 강화하면서도 React 애플리케이션이 백엔드 API와 원활하게 통신할 수 있도록 한다.


마무리

React(프론트엔드) 프록시 설정과 Spring(백엔드)의 SpringSecurity에 CORS설정을 추가한 후 React를 실행한 후 정상적으로 백엔드와 통신을 한다면 CORS설정은 완료된다.


반응형

'Front > React' 카테고리의 다른 글

React 설치 및 실행 / 프로젝트 구조 정리  (2) 2025.01.30
React 기본 개념 정리  (5) 2025.01.23

관련글 더보기

댓글 영역

>