MSA 프로젝트 중 인증 인가가 궁금했었는데 튜터님이 알아보라고 하셔서 이번 기회에 조사하게됐다.
📌참조
Gateway는 라우팅 및 프로토콜 변환을 담당하며 마이크로 서비스의 중개자 역할을 하는 서버이다. 이를 통해 서비스는 클라이언트와 독립적으로 확장할 수 있으며 보안, 모니터링을 위한 단일 제어 지점을 제공한다.
서비스가 적고 트래픽이 적다면 클라이언트에서 서비스를 직접 호출하고 각각의 서비스에서 모든 로직을 처리해도 큰 부담이 되지는 않는다. 그러나 스케일이 커지면 공통의 로직을 모든 서버에 적용하고 배포하는 것도 큰일이 될 수 있다. => 이러한 필요성을 위해 개발된 게 Gateway 패턴.
Gateway는 서버들에서 필요한 공통 로직을 통합하여 처리. 모든 서비스에서 필요한 유저 정보, 보안 정책 등을 Gateway에서 처리하고 이를 업스트림 서버로 넘겨준다.

Gateway는 요청이 오면 정의된 설정에 따라 요청을 라우팅하고 사전에 설정된 필터들을 작동되고 설정은 Route 단위로 구성이 되며 Route는 다시 Predicate와 Filter로 구성된다.
Predicate는 요청을 구분할 때 사용하는 값인데, Path, Method, Host 등으로 요청을 매칭하고 Filter는 매칭된 요청에 대한 전처리나 서비스의 응답에 대한 후처리를 구현.
Spring Cloud Gateway는 스프링 Webflux를 통해 구현되어 있으며 내부적으로 Reactor-Netty를 사용하여 비동기 처리를 지원하고 있다.
Passport는 사용자의 인증 정보를 담은 내부 전용 토큰으로, 서비스 간 통신 시 사용자 정보를 안전하게 전달하기 위해 사용된다. 넷플릭스에서 채택한 인증 방법인듯 하다.
Protobuf로 직렬화된 후 HMAC 서명을 통해 위·변조를 방지하고, 최종적으로 Base64로 인코딩되어 전달된다. 외부에서는 JWT를 사용하고, 내부에서는 Passport를 사용하는 구조다.

JWT 발급과 Passport 생성은 하나의 인증 서버에서 모두 처리하는 것이 이상적인 구조
Gateway로 요청을 보내면 Gateway가 JWT를 Passport Server에 전달하고 JWT 정보를 바탕으로 Passport를 생성한다. 그리고 그 Passport를 Protobuf로 직렬화 하고 HMAC 서명과 Base64 인코딩을 진행한다.
내부 서버에서는 이 Passport를 검증 후 사용자 정보를 추출한다.
public ResponseEntity<?> getProfile(@PassportUser Passport passport) {
Long memberId = passport.getMemberId();
...
}

PassportValidator는 모두 공통 모듈에 포함되어 있으며, Passport를 사용하는 각 서버에서 공통적으로 사용할 수 있도록 구성했다.게이트웨이는 공통 모듈이 필요 없고 나머지에서 필요로 한다.