Java & Spring

프론트엔드와 백엔드 연동 시 CORS 에러

ju_young 2024. 5. 17. 16:07
728x90

프론트엔드(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]

728x90