[MSA] chapter 7_API Gateway 설정과 JWT 인증 처리 방법

Updated:

Categories:

Tags: ,

📌 개인적인 공간으로 공부를 기록하고 복습하기 위해 사용하는 블로그입니다.
정확하지 않은 정보가 있을 수 있으니 참고바랍니다 :😸
[틀린 내용은 댓글로 남겨주시면 복받으실거에요]

인프런 Dowon Lee님의 Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) 강의를 듣고 정리한 필기입니다.😊
Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) 강의 들으러 가기👩‍🏫

API Gateway 설정과 JWT 인증 처리 방법

프로젝트 할 때 MSA 에서 가장 어려웠던 부분을 손꼽으라하면 API Gateway 설정하는 것 이었는데 특히, 요청을 보낼 포트 번호와 URI 설정, 그리고 JWT 인증 처리 방식이 혼란스러웠다.

1. API Gateway에서의 요청 라우팅 설정

API Gateway는 요청이 오면 각 마이크로서비스로 라우팅하는 역할을 하는데 요청은 어디로 보내야 하는지에 대해서 말하자면, API-Gateway에서 Config 파일 도는 application.yml에서 설정할 수 있다.

예시)

  • 예를 들어, user-service/health_check라는 엔드포인트가 있다고 가정
  • API-Gateway 파일에 Path를 Path = user-service/** 로 지정해 두었고 API-Gateway의 port번호가 8000이라면 localhost:8000/user-service/health_check로 요청하면 된다.
  • 만약 user-service에 endpoint가 “/health_check”로만 지정되어 있다면 404 NotFound가 발생한다.

  • 이 문제를 해결하려면 user-service에도 /user-service/health_check 경로로 엔드포인트를 설정해야 한다.

2. JWT 인증 처리 방식

두 번째로 복잡했던 부분은 Member 관련된 서비스에서 Security 적용 후에 API-Gateway는 로그인 후에 jwt Token으로 인증인가 처리를 어떻게 구성하는지이다.

로그인 성공 후 토큰 발급이 완료되면 클라이언트는 이 토큰을 저장하고, 다음에 서버로 요청을 보낼 때 Authorization 헤더에 Bearer 키워드와 함께 이 토큰을 포함하여 전송해야 한다.. 이후 요청받은 서버 또는 API Gateway에서는 토큰의 유효성을 검증(예: 서명이 유효한지, 만료되지 않았는지 등)한 후 요청을 처리하게 된다.

API Gateway 서비스에서 인증을 대신 처리하여 모든 API로 사용자의 요청을 넘길 수도 있고, user-serevice라는 서비스에서 인증을 처리하고 JWT를 확인하는 용도로만으로 사용해 볼 수 있는데, 강의에서는 후자 방식으로 구현되어있다.

AuthorizationHeaderFilter는 들어오는 요청의 Authorization 헤더를 검사하여 JWT 토큰의 유효성을 확인하고 유효하지 않은 경우에는 요청 처리를 중단하고 에러 응답을 반환한다. 토큰이 유효함을 인증받은 사용자는 권한이 필요한 자원에 접근할 수 있게 된다. 이는 마이크로서비스 간의 보안된 통신을 가능하게 하며, 각 서비스마다 별도의 인증처리를 하지 않아도 되는 이점을 제공해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//AuthorizationHeaderFilter class

//login -> token -> users (with token) -> header (include token)
@Override
public GatewayFilter apply (Config config) {
	retrun ((exchange , chain) -> {
		ServerHttpRequest request = exchange.getRequest();
		
		if (!request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) {
			return onError(exchange, "No authorization header", HttpStatus.UNAUTHORIZED);
		}
		
		String authorizationHeader = request.getHeaders.get(HttpHeaders.AUTHORIZATION).get(0);
		String jwt = authorization.replace("Bearer", "");
		
		if(!isJwtValid(jwt)) {
			return onError(exchange, "JWT token is not valid", HttpStatus.UNAUTHORIZED);
		}
		
		return chain.filter(exchange);
	});
}

private boolean isJwtVaild(String jwt) {
	boolean returnValue = true;
	String subject = null;
	
	try {
		subject = Jwts.parser().setSigningKey(env.getProperty("token.secret"))
							.parseClaimsJws(jwt).getBody()
							.getSubject();
	} catch (Exception ex) {
			returnValue = false;
	}
	return returnValue;
}

// Mono, Flux -> Spring Webflux
private Mono<void> onError (ServerWebExchange exchange, String err, HttpStatus httpStatus) {
	ServerHttpResponse response = exchange.getResponse();
	response.setStatusCode(hnttpStatus);
	
	log.error(err);
	return response.setComplete();
}
  • Authorization 헤더 확인: 요청에 Authorization 헤더가 없는 경우 에러를 반환한다.
  • JWT 토큰 유효성 검사: 헤더에서 추출한 JWT 토큰이 유효한지 확인한다. 이때 isJwtValid 메서드를 통해 서명 검증 및 만료 여부를 확인한다.
  • Spring WebFlux: 비동기 처리를 위해 Mono를 사용한다. Mono<Void>Flux는 각각 단일 값과 다중 값의 비동기 처리를 나타내며, Spring 5.0에서 WebFlux 프레임워크와 함께 제공된다.
  • token.secret은 user-service에서 사용하던 application.yml 값을 가져와서 API-Gateway의 application.yml에 넣어준다,


이렇게 Spring Cloud Gateway에서 요청 라우팅과 JWT 인증을 처리하는 방법을 통해 MSA 환경에서 클라이언트 요청을 안전하게 각 서비스로 전달할 수 있다. 이 과정에서 Spring Cloud Gateway의 필터 설정과 JWT 토큰 인증 처리는 API Gateway의 중요한 기능 중 하나로, 각 서비스 간의 통신 보안과 유연한 경로 관리를 가능하게 한다.

MSA 카테고리 내 다른 글 보러가기

Leave a comment