[Spring] CORS(Cross-Origin Resource Sharing) 오류와 해결 과정

Neo-Renaissance·2025년 1월 17일

CORS란 무엇인가?

CORS(Cross-Origin Resource Sharing)는 한 도메인에서 로드된 웹 애플리케이션이 다른 도메인에서 리소스를 요청할 때 발생하는 보안 메커니즘입니다. 브라우저는 보안상의 이유로 동일 출처 정책(Same-Origin Policy)을 따르며, 이를 우회하기 위해 CORS를 사용합니다.

CORS 오류가 발생하는 이유

CORS 오류는 프론트엔드(React)와 백엔드(Spring)를 서로 다른 도메인에서 실행할 때 주로 발생합니다. 예를 들어:

  • React 앱: http://localhost:3000
  • Spring 서버: http://localhost:8080

서로 다른 도메인 간 요청은 브라우저가 차단하며, 서버에서 이를 명시적으로 허용해야 합니다.

해결 방법

1. Spring Framework에서 CORS 설정

Spring Framework에서 CORS를 설정하는 방법은 여러 가지가 있습니다.

방법 1: @CrossOrigin 애노테이션 사용

특정 컨트롤러나 메서드 수준에서 CORS를 설정할 수 있습니다.

@RestController
@RequestMapping("/api")
public class ApiController {

    @CrossOrigin(origins = "http://localhost:3000")
    @GetMapping("/data")
    public ResponseEntity<String> getData() {
        return ResponseEntity.ok("Hello from Spring!");
    }
}

방법 2: 글로벌 설정

글로벌 CORS 설정은 애플리케이션 전역에 대해 적용됩니다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**")
                        .allowedOrigins("http://localhost:3000")
                        .allowedMethods("GET", "POST", "PUT", "DELETE")
                        .allowedHeaders("*")
                        .allowCredentials(true);
            }
        };
    }
}

2. Spring Security와 함께 CORS 설정

Spring Security를 사용하는 경우, Security 설정에서도 CORS를 명시적으로 허용해야 합니다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .cors()
            .and()
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/**").permitAll();

        return http.build();
    }
}

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.addAllowedOrigin("http://localhost:3000");
    configuration.addAllowedMethod("*");
    configuration.addAllowedHeader("*");
    configuration.setAllowCredentials(true);

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/api/**", configuration);
    return source;
}
profile
if (실패) { 다시 도전; } else { 성공; }

0개의 댓글