API 게이트웨이란?
- API 게이트웨이는 클라이언트의 요청을 받아 백엔드 서비스로 라우팅하고, 다양한 부가 기능을 제공하는 중간 서버입니다.
- 클라이언트와 서비스 간의 단일 진입점 역할을 하며, 보안, 로깅, 모니터링, 요청 필터링 등을 처리합니다.
API 게이트웨이의 주요 기능
- 라우팅: 클라이언트 요청을 적절한 서비스로 전달
- 인증 및 권한 부여: 요청의 인증 및 권한을 검증
- 로드 밸런싱: 여러 서비스 인스턴스 간의 부하 분산
- 모니터링 및 로깅: 요청 및 응답을 로깅하고 모니터링
- 요청 및 응답 변환: 요청과 응답을 변환하거나 필터링
라우팅 설정
server:
port: 19091
spring:
application:
name: gateway-service
main:
web-application-type: reactive
cloud:
gateway:
routes:
- id: order-service
uri: lb://order-service
predicates:
- Path=/order/**
- id: product-service
uri: lb://product-service
predicates:
- Path=/products/**
- id: auth-service
uri: lb://auth-service
predicates:
- Path=/auth/**
discovery:
locator:
enabled: true
service:
jwt:
secreat-key: "3UMzr1agWuUOpd2Ypm1BfGv3c7GLj0l3ToEYrAk/GXvQVmOyG27VVZ6tAhYHg+pubxhLYLO/ACcbpoEYo++Cjg=="
eureka:
client:
service-url:
defaultZone: http://localhost:19090/eureka/
의존성 설정
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'io.jsonwebtoken:jjwt:0.12.6'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
}
JWT 검증 필터
package com.sparta.msa_exam.gateway.filter;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import javax.crypto.SecretKey;
@Component
@Slf4j
public class JwtAuthenticationFilter implements GlobalFilter {
@Value("${service.jwt.secreat-key}")
private String secretKey;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
if (path.equals("/auth/signIn") || path.equals("/auth/signUp")) {
return chain.filter(exchange);
}
String token = getToken(exchange);
log.info(token);
if (token == null || !validateToken(token, exchange)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
private String getToken(ServerWebExchange exchange) {
String authorization = exchange.getRequest().getHeaders().getFirst("Authorization");
if (authorization != null && authorization.startsWith("Bearer ")) {
return authorization.substring(7);
}
return null;
}
private boolean validateToken(String token, ServerWebExchange exchange) {
try {
SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secretKey));
Jws<Claims> claimsJws = Jwts.parser()
.verifyWith(key)
.build().parseSignedClaims(token);
log.info("payload: {}", claimsJws.getPayload().toString());
Claims claims = claimsJws.getBody();
exchange.getRequest().mutate()
.header("X-Role", claims.get("role").toString())
.build();
return true;
} catch (Exception e) {
log.warn("validateToken : ", e);
return false;
}
}
}
게이트웨이 실습 흐름도
'MSA' 카테고리의 다른 글
분산 추적(Spring Cloud Sleuth) 및 로깅(Zipkin) 이론 및 실습 (0) | 2024.08.10 |
---|---|
2024-08-05(TIL) - 서킷브레이커 (0) | 2024.08.06 |
2024-08-02(TIL) - Eureka, 로드밸런싱 복습 (0) | 2024.08.02 |
2024-08-01(TIL) - Spring Cloud 주요 기능 (0) | 2024.07.31 |