Spring Boot는 API 서버, React는 화면(UI)을 담당하는 구조로 분리하여
프론트엔드와 백엔드를 독립적으로 개발하기 위해 React를 결합하였다.
이 경우 두 서버의 포트가 달라지므로 브라우저 보안 정책에 따라 CORS 에러가 발생한다.

 

1. 리액트 설치 : npm create vite@latest

2. 서버와 연결을 위해 axios 설치 : npm install axios

3. 리액트 실행 : npm run dev

 

Spring Boot 서버에 접근하여 데이터를 받아오기 위해 axios를 임포트하고 코드를 추가한다.

const [sessionInfo, setSessionInfo] = useState("데이터를 가져오는 중...");

  useEffect(() => {
    // 스프링 부트에서 만든 세션 체크 API 호출
    axios.get('http://localhost:8080/check', {
      withCredentials: true // 세션 쿠키를 함께 보내기 위한 필수 옵션!
    })
    .then(response => {
      setSessionInfo(JSON.stringify(response.data));
    })
    .catch(error => {
      setSessionInfo("에러 발생! 콘솔(F12)을 확인하세요.");
      console.error("통신 에러:", error);
    });
  }, []);

 

리액트는 외부 데이터(API) 호출 표준 패턴으로 axios를 사용한다.

 

1. useState 정의 : 리액트는 변수의 값이 변경되어도 자동으로 새로고침 되지 않는다. 

                             setSessionInfo를 통해 값을 변경해야만 화면이 새로고침 된다.

2. useEffect : useEffect 없이 axios.get을 사용하면 화면이 그려질 때 API를 무한 호출

                      useEffect(() => {...}, []); 마지막에 붙는 빈 배열의 의미는 
                      "이 페이지가 처음으로 그려질 때 딱 한 번만 코드를 실행"의 의미를 가진다.

3.axios.get('url', {withCredentials: true}) : url에 get으로 접근한다.

                          withCredentials:true => 리액트가 가진 세션의 정보를 서버에 전달

4. then(response => {}) 서버에서 보낸 JSON 데이터가 리액트의 response 객체로 들어옴

 

 

 

리액트 서버 URL CORS 허용을 위해 아래의 코드를 SecurityConfig에 추가한다.

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();

    // 리액트 서버 주소 허용
    configuration.setAllowedOrigins(List.of("http://localhost:5173"));
    configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
    configuration.setAllowedHeaders(List.of("*"));

    // 자격 증명(쿠키/세션) 허용
    configuration.setAllowCredentials(true);

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

 

Spring Security는 자체 필터 체인을 사용하기 때문에,
CORS 설정을 SecurityFilterChain에 직접 등록하지 않으면
브라우저 요청이 Security 단계에서 차단되므로 filterChain 에도 추가해준다

.cors(cors -> cors.configurationSource(corsConfigurationSource()))

 

 

setAllowCredentials(true) 를 사용할 때는 서버 주소를 와일드카드(*)로 사용할 수 없다.

특정 URL을 명시하여야 쿠키 전송이 허용된다.

+ Recent posts