Spring Cloud Gateway에서 CORS(Cross-Origin Resource Sharing) 지원

2024. 12. 15. 15:37Spring Microservice

Spring Cloud Gateway에서 CORS(Cross-Origin Resource Sharing)를 지원하려면, Spring Framework의 CorsConfiguration과 관련된 설정을 활용하여 Gateway에 들어오는 요청의 CORS 정책을 명시적으로 구성해야 합니다. Spring Cloud Gateway는 Spring WebFlux 기반이므로, WebFlux의 CORS 처리 방식을 사용합니다.

아래는 CORS를 Spring Cloud Gateway에서 지원하는 방법을 단계별로 설명한 내용입니다.


1. Spring Cloud Gateway에서 CORS 지원 방식

Spring Cloud Gateway에서 CORS 정책을 설정하는 주요 방식은 두 가지입니다:

  1. Global CORS 설정:

    • 모든 라우트에 대해 전역적으로 CORS 정책을 설정합니다.
    • CorsConfiguration을 사용하여 특정 Origin, 메서드, 헤더를 허용.
  2. 개별 Route 레벨 CORS 설정:

    • 특정 라우트에 대해 별도의 CORS 정책을 설정합니다.
    • 라우트별로 허용할 Origin, 메서드 등을 세분화.

2. Global CORS 설정

Spring Cloud Gateway에 들어오는 모든 요청에 대해 동일한 CORS 정책을 적용하려면, 전역적으로 CORS를 설정할 수 있습니다.

Global CORS 설정 방법

  1. CorsConfiguration을 사용한 설정

Spring Cloud Gateway Application 설정 코드:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsConfigurationSource;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.server.WebFilter;

@Configuration
public class GatewayCorsConfig {

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("http://example.com"); // 허용할 Origin
        config.addAllowedMethod("*"); // 모든 HTTP 메서드 허용 (GET, POST 등)
        config.addAllowedHeader("*"); // 모든 헤더 허용
        config.setAllowCredentials(true); // 쿠키를 포함한 인증 허용

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config); // 모든 경로에 CORS 설정 적용
        return source;
    }

    @Bean
    public WebFilter corsFilter(CorsConfigurationSource corsConfigurationSource) {
        return new org.springframework.web.cors.reactive.CorsWebFilter(corsConfigurationSource);
    }
}
  1. 설명
    • CorsConfiguration 객체를 생성해 허용할 Origin, 메서드, 헤더 등을 정의합니다.
    • UrlBasedCorsConfigurationSource로 경로와 CORS 설정을 매핑합니다.
    • CorsWebFilter를 빈으로 등록하여 Gateway의 요청에 적용합니다.

3. Application Properties를 활용한 CORS 설정

Spring Cloud Gateway는 기본적으로 application.yml 파일에서 CORS 정책을 설정할 수 있습니다.

application.yml 예제

spring:
  cloud:
    gateway:
      globalcors:
        corsConfigurations:
          '[/**]': # 모든 경로에 대해 설정
            allowedOrigins:
              - "http://example.com"  # 허용할 Origin
            allowedMethods:
              - "GET"
              - "POST"
              - "PUT"
              - "DELETE"
            allowedHeaders:
              - "*"
            allowCredentials: true

설명

  • [/**]: 모든 경로에 대해 CORS 정책을 적용.
  • allowedOrigins: 허용할 클라이언트 도메인.
  • allowedMethods: 허용할 HTTP 메서드.
  • allowedHeaders: 허용할 요청 헤더.
  • allowCredentials: 쿠키와 같은 인증 정보를 포함할지 여부.

4. 특정 Route에 CORS 설정 적용

Spring Cloud Gateway에서 특정 라우트에만 CORS를 설정하려면 RouteDefinition을 활용하거나 Java DSL로 구성합니다.

Java DSL로 특정 Route CORS 설정

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsConfigurationSource;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.server.WebFilter;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;

@Configuration
public class GatewayRouteConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("example_route", r -> r
                .path("/api/example/**")
                .filters(f -> f.addRequestHeader("X-Example", "Gateway"))
                .uri("http://localhost:8081"))
            .build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("http://example.com");
        config.addAllowedMethod("GET");
        config.addAllowedHeader("*");
        config.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/example/**", config); // 특정 경로에만 CORS 설정
        return source;
    }

    @Bean
    public WebFilter corsFilter(CorsConfigurationSource corsConfigurationSource) {
        return new org.springframework.web.cors.reactive.CorsWebFilter(corsConfigurationSource);
    }
}

설명

  • /api/example/** 경로에만 CORS 정책을 적용.
  • CorsConfigurationSourceCorsWebFilter를 통해 특정 경로를 세분화해 관리.

5. 테스트 시 주의점

  1. Preflight 요청

    • CORS 요청은 브라우저가 사전 요청(Preflight Request)을 보내는 경우가 많습니다.
    • Preflight 요청(OPTIONS 메서드)에 대한 응답을 적절히 처리해야 합니다.
  2. DevTools와 같은 환경

    • Spring Boot DevTools가 활성화된 경우, 자동 리로드로 인해 CORS 관련 오류가 발생할 수 있습니다. 이 경우 DevTools를 일시적으로 비활성화하거나 관련 설정을 수정합니다.

6. Gateway와 Backend 간 CORS 정책

  1. API Gateway가 요청을 백엔드로 전달할 때

    • API Gateway에서 클라이언트 요청의 CORS를 처리하고, 백엔드 서버는 Gateway의 요청만 처리하도록 설정.
    • 백엔드 서버는 추가적인 CORS 정책이 필요하지 않음.
  2. Gateway를 거치지 않는 요청

    • 개발 환경에서 CORS 오류를 방지하기 위해 백엔드 서버에도 동일한 CORS 정책을 설정할 수 있음.

7. 결론

  • Global CORS 설정: 모든 경로에 대해 일관된 CORS 정책을 적용하려면 CorsConfigurationCorsWebFilter를 사용.
  • Route별 CORS 설정: 특정 경로에만 CORS 정책을 적용하려면 CorsConfigurationSource를 활용하여 경로를 세분화.
  • application.yml 설정: 간단한 전역 설정에는 spring.cloud.gateway.globalcors를 활용.

Spring Cloud Gateway에서 CORS를 적절히 설정하면 클라이언트-서버 간의 원활한 통신이 가능하며, 보안 정책을 유지하면서도 필요한 요청을 허용할 수 있습니다.

'Spring Microservice' 카테고리의 다른 글

Microservices architecture design  (0) 2025.02.26
Promethous/Grafana  (0) 2024.12.22
Reverse Proxy  (0) 2024.12.15
spring cloud gateway의 route predicate factories  (0) 2024.12.15
@CircuitBreaker의 name 속성  (0) 2024.12.12