CORS(Cross-Origin Resource Sharing)는 한 도메인에서 로드된 웹 애플리케이션이 다른 도메인에서 리소스를 요청할 때 발생하는 보안 메커니즘입니다. 브라우저는 보안상의 이유로 동일 출처 정책(Same-Origin Policy)을 따르며, 이를 우회하기 위해 CORS를 사용합니다.
CORS 오류는 프론트엔드(React)와 백엔드(Spring)를 서로 다른 도메인에서 실행할 때 주로 발생합니다. 예를 들어:
http://localhost:3000http://localhost:8080서로 다른 도메인 간 요청은 브라우저가 차단하며, 서버에서 이를 명시적으로 허용해야 합니다.
Spring Framework에서 CORS를 설정하는 방법은 여러 가지가 있습니다.
@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!");
}
}
글로벌 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);
}
};
}
}
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;
}