CORS 문제

임지원·2024년 6월 9일

문제상황

Spring으로 백을 만들고 react로 프론트를 만들기 위해 연결 테스트를 하던 중 cors문제가 발생했다.

해결과정

부트캠프에서 프로젝트로 했던 조합이었기에 우리 대장님이 만들어준 코드를 보며 복습하고 모르는 점을 정리하기로 했다.


학습

CORS란?

CORS(Cross-Origin Resource Sharing)
CORS란 도메인이 다른 서버끼리 리소스를 주고 받을 때 보안을 위해 설정된 정책이다.

React 프론트(3000)와 Spring(8090) 이기 때문에 포트가 달라 서로 다른 CORS 위반 에러가 발생한다.

다른 Origin을 갖고있는 react와 spring이 통신해주기 위해 설정이 필요함을 알았다.

Spring 설정

webConfig만들어주기

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://localhost:3000/")
                .allowedMethods("*")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }

}
  1. @Configuration : 어노테이션을 이용해 설정 파일로 등록한다.
  2. implements WebMvcConfigurer : WebMvcConfigurer 인터페이스를 구현하여 SpringMVC에 대한 추가 설정 제공
  3. addCorsMappings : CORS 매핑을 추가하는 메서드
  4. addMapping("/api/**") : CORS를 적용할 URL패턴을 정의한다. (/api/~ 로 들어오는 URL에 적용한다)
  5. .allowedOrigins("http://localhost:3000/") : 자원 공유를 허락할 Origin설정(현재는 프론트 서버만 허락)
  6. .allowedMethods("*") : 모든 HTTP메서드를 허용한다.
  7. .allowedHeaders("*") : 모든 HTTP헤더를 허용한다.
  8. .allowCredentials(true) : 쿠키와 인증 정보를 포함한 크로스 도메인 요청을 허용한다.
  9. .maxAge(3600); : CORS설정이 캐시되는 시간을 3600초(1시간)으로 설정

React 설정

axios 설정, HttpGet 함수화

import axios from "axios";

const apiInstance = axios.create({
  baseURL: "http://localhost:8090",
  headers: {
    "Content-Type": "application/json",
  },
  // timeout: 10000,
  withCredentials: true,
});
  • http 요청을 쉽게해주는 axios의 기본 설정을 정의하였다.
  1. apiInstance라는 axios인스턴스 만들기
  2. baseURL 백엔드 서버 포트로 맞추기
  3. header의 요청 타입을 json으로 설정
  4. withCredentials로 쿠키와 인증정보를 포함한 요청 허용
export const HttpGet = async (url, params = null) => {
  try {
    const response = await apiInstance.get(url, { params });
    // console.log("GET request sent to:", response.config.url);

    return response.data;
  } catch (error) {
    console.error("Error in HttpGet:", error);
    throw error;
  }
};
  1. URL과 선택적param을 통해 GET요청하기
  2. url에는 엔드포인트가 들어간다(/api/~), param에는 쿼리 파라미터가 들어간다
    HttpGet('/api', { id: 1 })는 http://localhost:8090/api?id=1로 요청이 간다.
  3. 성공하면 data에 내용이 저장된다.
  4. 실패하면 catch에서 오류를 처리한다.

사용

import { HttpGet } from "./service/httpService";
import React from "react";
import { useState, useEffect } from "react";

function App() {
   const [hello, setHello] = useState('')

    useEffect(() => {
        HttpGet("/api/hello").then((data)=>{
            if(data) {
                setHello(data);
            }
        });
    }, []);

    return (
        <div>
            데이터 가져오기 = {hello}
        </div>
    );
}

export default App;
@RestController
public class MemberController {
    @GetMapping("/api/hello")
    public String test() {
        return "Hello, world!";
    }
}

성공

가져와 졌다. 성공....

profile
백엔드 새싹

0개의 댓글