0. API Gateway 에서의 CORS 설정
현재 개발 중인 프로젝트의 백엔드 서버는 MSA 구조로 개발되어 있어서, 프론트엔드 서버의 요청을 아래와 같은 흐름으로 받아들이고 있습니다.
클라이언트의 요청을 API Gateway 가 받아서, URI 를 확인해서 적절한 마이크로 서비스로 요청을 라우팅하는 형태입니다.
이 때, API Gateway는 클라이언트 요청에 대해 CORS 설정을 추가해야 합니다.
CORS 에 대한 내용은 아래 포스팅을 참고해주세요.
https://byunsw4.tistory.com/22
API Gateway 에 클라이언트 요청에 대한 CORS설정을 추가하게 된다면, 아래와 같은 흐름으로 요청이 흘러가게 됩니다.
위 같은 형태를 설정하기 위해, Spring Cloud Gateway 에선 어떻게 CORS 를 적용하는지 알아보았습니다.
1. Spring Cloud Gateway 에서 전체적으로 CORS 적용
현재 개발 중인 프로젝트는 Spring Cloud 기반으로 MSA 구조가 구현되어 있기 때문에, API Gateway 역할을 Spring Cloud Gateway 를 사용합니다.
Spring Cloud Gateway 에서는 아래와 같이 CORS 를 설정하도록 가이드하고 있습니다.
https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/cors-configuration.html
위 설정을 제 API Gateway 프로젝트에 적용했을 때, 아래와 같이 적용되었습니다.
# application.yml
spring:
config:
activate:
on-profile: local
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allow-credentials: true
allowed-origins: "http://localhost:3000"
allowed-headers: "*"
allowed-methods:
- PUT
- GET
- POST
- DELETE
- OPTIONS
Spring Cloud 는 내부적으로 요청 URI 에 대한 CORS 옵션을 Map 형태로 저장합니다.
고로 위 설정은, 모든 URI 요청 (/**) 에 대해 아래와 같은 옵션을 적용하는 설정입니다.
- http://localhost:3000 으로의 요청은 모두 허용한다.
- 모든 Request Header 값을 허용한다.
- PUT / GET / POST / DELETE / OPTIONS 로 온 요청은 허용한다.
2. 여러 도메인에 CORS global 적용하기
API Gateway 는 클라이언트의 요청이 통과하는 관문과 같은 역할을 수행하기 때문에, 많은 클라이언트의 요청이 집중될 수 밖에 없습니다.
그 클라이언트는 같은 시스템으로써 서비스되는 프론트엔드 혹은 모바일 서버일 수 도 있고, 다른 외부 시스템일 수 도 있습니다.
즉, 모든 클라이언트가 서비스하는 도메인이 다 다를 경우, API Gateway 는 이에 대해 CORS 를 적용해주어야 합니다.
Spring Cloud 가 어떻게 Global CORS 를 등록하는지, 찾아보던 중 아래 코드를 찾을 수 있었습니다.
```GatewayAutoConfiguration.java
@Configuration(proxyBeanMethods = false) // 여러 annotation 이 있지만, 나머진 생략
public class GatewayAutoConfiguration {
// 중략
@Bean
public GlobalCorsProperties globalCorsProperties() {
return new GlobalCorsProperties();
}
// 중략
}
```GlobalCorsProperties.java
@ConfigurationProperties("spring.cloud.gateway.globalcors")
public class GlobalCorsProperties {
private final Map<String, CorsConfiguration> corsConfigurations = new LinkedHashMap<>();
public Map<String, CorsConfiguration> getCorsConfigurations() {
return corsConfigurations;
}
}
```CorsConfiguration.java
public class CorsConfiguration {
// 중략
@Nullable
private List<String> allowedOrigins;
// 중략
}
의미를 대략 요약하자면, 다음으로 해석됩니다.
- GatewayAutoConfigration.java 가 @Configuration 에 의해, @Bean 이 붙은 GlobalCorsProperties를 스프링 Bean 으로 등록한다.
- GlobalCorsProperties.java 는 @ConfigurationProperties("spring.cloud.gateway.globalcors") 에 의해 properties 파일(application.properties 혹은 application.yml) 내에 spring.cloud.gateway.globalcors 하위에 정보를 Map<String, CorsConfiguration> 형태로 생성한다.
- CorsConfiguration 이 생성되면서, properties 파일의 allowedOrigins 의 값을 List 로 저장한다.
위 과정을 미루어 봤을 때, 공식문서에 나와있진 않지만 yml 설정의 value 가 List 로 인식되는 형태로 설정하면 된다는 것을 알 수 있습니다.
#application.yml
spring:
config:
activate:
on-profile: local
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allow-credentials: true
# 이것도 가능
#allowed-origins: "http://localhost:3000, http://localhost:3001"
allowed-origins:
- http://localhost:3000
- http://localhost:3001
allowed-headers: "*"
allowed-methods:
- PUT
- GET
- POST
- DELETE
- OPTIONS
yml 파일 문법 참고 : https://namu.wiki/w/YAML
'DDD&MSA' 카테고리의 다른 글
[MSA] Feign Client 테스트 작성기 - wireMockServer 사용기 (0) | 2023.11.14 |
---|---|
[MSA] Feign Client - 마이크로 서비스 간 통신 구현하기 (0) | 2023.11.08 |
[MSA] API Gateway 에 인증 구현하기 - GatewayFilter 추가하기 (0) | 2023.10.08 |
[MSA] API Gateway - 마이크로 서비스 Routing 처리하기(feat. Spring Cloud Gateway) (0) | 2023.09.28 |
[MSA] Micro Service Architecture(MSA) 시작하기 - Eureka Server & Client (0) | 2023.09.10 |
댓글