반응형
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, WebClient.Builder webClientBuilder) {
WebClient webClient = webClientBuilder.build();
return builder.routes()
.route("auth_route", r -> r.path("/api/**")
.filter((exchange, chain) -> {
// 클라이언트 요청에서 Bearer 토큰 추출
String token = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
if (token != null && token.startsWith("Bearer ")) {
token = token.replace("Bearer ", "");
// 인증 서버에 토큰 검증 요청
return webClient.post()
.uri("http://your-auth-server-url/validate")
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
.retrieve()
.onStatus(HttpStatus::is4xxClientError, clientResponse -> {
// 인증 실패 처리
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
})
.flatMap(clientResponse -> {
// 인증 성공 처리
if (clientResponse.statusCode().is2xxSuccessful()) {
// 원래 요청을 계속 처리
return chain.filter(exchange);
} else {
// 다른 상태 코드 처리 (필요 시)
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
return exchange.getResponse().setComplete();
}
});
} else {
// 토큰이 없거나 잘못된 경우 401 반환
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
})
.uri("http://your-backend-service-url")) // 실제 서비스 URI
.build();
}
}
spring:
cloud:
gateway:
routes:
- id: auth_route
uri: http://your-backend-service-url # 실제 서비스 URI
predicates:
- Path=/api/**
filters:
- RemoveRequestHeader=Authorization # Authorization 헤더 제거 (옵션)
- AddRequestHeader=X-Request-ID, some-unique-id # 요청 ID 추가
- SetResponseHeader=X-Response-Time, "#{T(java.lang.System).currentTimeMillis()}" # 응답 시간 헤더 추가