Passport

남예준·2025년 11월 17일

MSA 프로젝트 중 인증 인가가 궁금했었는데 튜터님이 알아보라고 하셔서 이번 기회에 조사하게됐다.

📌

참조

Gateway

Gateway는 라우팅 및 프로토콜 변환을 담당하며 마이크로 서비스의 중개자 역할을 하는 서버이다. 이를 통해 서비스는 클라이언트와 독립적으로 확장할 수 있으며 보안, 모니터링을 위한 단일 제어 지점을 제공한다.

서비스가 적고 트래픽이 적다면 클라이언트에서 서비스를 직접 호출하고 각각의 서비스에서 모든 로직을 처리해도 큰 부담이 되지는 않는다. 그러나 스케일이 커지면 공통의 로직을 모든 서버에 적용하고 배포하는 것도 큰일이 될 수 있다. => 이러한 필요성을 위해 개발된 게 Gateway 패턴.

Gateway는 서버들에서 필요한 공통 로직을 통합하여 처리. 모든 서비스에서 필요한 유저 정보, 보안 정책 등을 Gateway에서 처리하고 이를 업스트림 서버로 넘겨준다.

Gateway는 요청이 오면 정의된 설정에 따라 요청을 라우팅하고 사전에 설정된 필터들을 작동되고 설정은 Route 단위로 구성이 되며 Route는 다시 Predicate와 Filter로 구성된다.

Predicate는 요청을 구분할 때 사용하는 값인데, Path, Method, Host 등으로 요청을 매칭하고 Filter는 매칭된 요청에 대한 전처리나 서비스의 응답에 대한 후처리를 구현.

Spring Cloud Gateway는 스프링 Webflux를 통해 구현되어 있으며 내부적으로 Reactor-Netty를 사용하여 비동기 처리를 지원하고 있다.

Passport

Passport는 사용자의 인증 정보를 담은 내부 전용 토큰으로, 서비스 간 통신 시 사용자 정보를 안전하게 전달하기 위해 사용된다. 넷플릭스에서 채택한 인증 방법인듯 하다.

Protobuf로 직렬화된 후 HMAC 서명을 통해 위·변조를 방지하고, 최종적으로 Base64로 인코딩되어 전달된다. 외부에서는 JWT를 사용하고, 내부에서는 Passport를 사용하는 구조다.

JWT 발급과 Passport 생성은 하나의 인증 서버에서 모두 처리하는 것이 이상적인 구조

  • 토스가 Passport를 택한 이유 유저 Passport 토스 내부 서비스들도 기존에는 모든 서비스에서 유저 정보가 필요할 때 유저 API를 호출하는 방식으로 유저 정보를 가져오고 있었는데요 이는 트랜잭션 내에 불필요한 중복 요청을 유발하고 서버 리소스의 낭비로 이어졌습니다. 이를 개선하기 위해 저희는 Netflix의 Passport 구조를 참고하였습니다. Netflix는 유저 인증 시에 Passport 라는 id 토큰을 트랜잭션 내로 전파하는 방법을 사용하고 있는데요. 저희는 Netflix의 Passport 구조를 저희 팀에 맞게 변경하여 토스 Passport를 구현했습니다. Passport는 사용자 기기 정보와 유저 정보를 담은 하나의 토큰인데요. 앱에서 유저 식별키와 함께 API를 요청하게 되면 Gateway에서 이 키를 토대로 인증 서버에 Passport를 요청합니다. Passport에는 디바이스 정보와 유저 정보가 담겨 있으며 Gateway는 이를 serialize 하여 서비스에 전파합니다. 유저 정보가 필요한 서비스는 유저 정보 호출 없이 Passport 정보를 통하여 유저에 대한 정보를 사용할 수 있습니다.

흐름

Gateway로 요청을 보내면 Gateway가 JWT를 Passport Server에 전달하고 JWT 정보를 바탕으로 Passport를 생성한다. 그리고 그 Passport를 Protobuf로 직렬화 하고 HMAC 서명과 Base64 인코딩을 진행한다.

내부 서버에서는 이 Passport를 검증 후 사용자 정보를 추출한다.

public ResponseEntity<?> getProfile(@PassportUser Passport passport) {
    Long memberId = passport.getMemberId();
    ...
}

  1. 공통 모듈
    • @PassportUser, WebMvcConfig, PassportArgumentResolver, HmacUtil, PassportValidator모두 공통 모듈에 포함되어 있으며, Passport를 사용하는 각 서버에서 공통적으로 사용할 수 있도록 구성했다.
    • Passport의 검증 및 사용자 정보 추출 과정을 어노테이션 기반으로 자동화하여, 개발자의 편의성을 높이기 위해 설계했다.
  2. Gateway (공통 모듈 X)
    • Gateway는 공통 모듈에 대한 의존성 없이 동작하며, 요청에 JWT가 포함되어 있는지 검사한다.
    • JWT가 있을 경우, Passport 생성을 위해 Passport Server에 생성 요청을 보낸다.
    • JWT가 없는 경우, 인증되지 않은 요청으로 간주하여 예외를 발생시킨다.
  3. Passport Server (공통 모듈 O)
    • Passport Server는 공통 모듈에 포함된 HmacUtil을 사용하여 Passport에 대한 HMAC 서명을 계산한다.
    • 직렬화된 Passport 원본과 HMAC을 결합한 후 Base64로 인코딩하여 반환한다.
  4. Passport를 사용하는 다른 서버 (공통 모듈 O)
    • Passport를 사용하는 각 서버는 공통 모듈에 포함된 PassportArgumentResolver와 PassportValidator를 통해, Base64로 인코딩된 Passport를 디코딩하고 HMAC 서명을 검증한 뒤 사용자 정보를 추출한다.
    • 컨트롤러에서는 @PassportUser 어노테이션을 사용해 Passport 객체를 자동으로 주입받을 수 있어, 개발자가 사용자 정보를 더욱 편리하게 사용할 수 있다.

게이트웨이는 공통 모듈이 필요 없고 나머지에서 필요로 한다.

0개의 댓글