프론트엔드(React) 애플리케이션을 실행하면 localhost:5173
, 백엔드(Spring Boot) 애플리케이션을 실행하면 localhost:8080
이 지정된다고 할 때 프론트엔드에서 백엔드로 API 요청을 하게되면 CORS(Cross-Origin Resource Sharing)에러가 발생한다.
NOTE
CORS(Cross-Origin Resource Sharing) 에러는 서로 다른 두 서버 간의 Origin(Protocol + Hostname + Port)이 다를 경우 발생한다.
CORS에러를 해결하기위해 다음과 같은 방법들을 적용할 수 있다.
1. WebMvcConfigurer
@Configuration
@EnableScheduling
@EnableTransactionManagement
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:5173")
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE");
}
}
2. Spring Security의 SecurityFilterChain
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.csrf()
.disable()
.cors(cors -> cors.configurationSource(request -> {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Collections.singletonList("http://localhost:5173"));
config.setAllowedMethods(Collections.singletonList("*"));
config.setAllowCredentials(true);
config.setAllowedHeaders(Collections.singletonList("*"));
return config;
}))
.authorizeHttpRequests(auth -> auth.requestMatchers(
PathRequest.toStaticResources().atCommonLocations())
.permitAll()
.anyRequest()
.authenticated())
.build();
}
3. Nginx 설정
브라우저는 서버에 초기 요청 시 서버가 CORS 프로토콜을 이해했는지 확인한다. 이 요청을 preflight request
라 부르며 OPTIONS
메소드를 사용한다.
server {
listen 8080;
server_name localhost;
location /api {
# preflight response
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'http://localhost:5173';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Allow-Credentials' 'true';
return 204;
}
proxy_pass http://backend/api;
add_header 'Access-Control-Allow-Origin' 'http://localhost:5173';
add_header 'Access-Control-Allow-Credentials' 'true';
}
}
[reference]