분산 환경에서의 SSO 통합과 Soft FK 활용기
백엔드 개발을 하다 보면 필연적으로 '인증'을 마주하게 됩니다. 초기에는 단순히 유저 ID와 비밀번호를 확인하고 JWT(JSON Web Token) 문자열을 던져주는 API 하나면 충분하다고 생각하기 쉽습니다. 하지만 서비스가 확장되고 여러 개의 사내 시스템이 생겨나면서, 인증은 완전히 다른 차원의 난제가 됩니다.
사내 여러 서비스의 인증 체계를 통합하기 위해 '통합 회원 관리 서버' 를 단독으로 설계하고 구축하면서 겪었던 고민, 특히 물리적으로 분리된 데이터베이스 환경에서 유저를 어떻게 식별하고 통제할 것인지에 대한 아키텍처적 의사결정 과정을 공유하고자 합니다.
The Problem: 파편화된 인증과 분리된 데이터베이스
1. 파편화된 보안 정책과 신뢰 모델의 부재 기존 사내 서비스들은 각자 독립적으로 인증을 관리하고 있었습니다. 어떤 서비스는 토큰 만료 시간이 길고, 어떤 서비스는 짧았으며, JWT Secret Key 관리도 혼재되어 보안 수준이 제각각이었습니다. 클라이언트 중심의 파편화된 인증이 아니라, 서버 간(Server-to-Server)의 명확한 신뢰 모델을 보장하는 중앙 집중형 플랫폼 이 절실했습니다.
2. 분리된 DB 환경에서의 유저 식별 (FK 설계의 난제) 가장 큰 아키텍처적 고민은 데이터의 물리적 분리였습니다. 유저의 민감한 인증 정보는 새로 구축할 '통합 회원 서버'가 중앙에서 관리해야 했지만, 주문이나 도메인 같은 비즈니스 데이터는 기존의 '개별 서비스 DB'에 남아야 했습니다. 물리적으로 다른 데이터베이스를 사용하므로, RDBMS의 강력한 무기인 Foreign Key를 직접 연결할 수 없었고, 이는 곧 데이터 정합성 유지와 장애 추적의 어려움으로 직결되었습니다.
The Solution: 구조적 분리와 선언적 통제
1. JWT Payload와 Soft FK를 활용한 느슨한 결합 DB가 분리된 환경을 극복하기 위해 Soft FK (논리적 외래 키) 개념을 도입했습니다. 통합 회원 서버가 로그인에 성공한 유저에게 고유한 식별자(UUID)를 발급하고, 이를 Access Token의 Payload에 담아 클라이언트에 전달합니다. 클라이언트가 개별 비즈니스 서비스에 요청을 보낼 때 이 토큰을 제출하면, 개별 서비스는 토큰에서 UUID를 추출해 자신들의 DB에 'Soft FK'로 저장합니다.
이를 통해 통합 서버와 개별 서비스 간에 물리적인 DB 결합 없이도 유저를 식별하고 데이터를 완벽하게 매핑할 수 있었습니다.
2. 중앙 통제력을 잃지 않는 토큰 정책
- Access Token (10분): 유효기간을 짧게 가져가고, 개별 서비스가 자체적으로 검증하도록 하여 통합 서버의 부하를 분산시켰습니다.
- Refresh Token (7일): 갱신 요청은 반드시 통합 회원 서버를 거치도록 설계 했습니다. 특히 Refresh Token을 Prisma를 통해 DB에 저장하여 중앙에서 관리함으로써, 보안 이슈 발생 시 DB 레코드 삭제만으로 특정 디바이스나 유저를 즉각적으로 '강제 로그아웃' 시킬 수 있는 강력한 통제권을 확보했습니다.
3. Express에서 NestJS로: 선언적 파이프라인 구축
단순한 로직 구현을 넘어, 확장 가능하고 우아한 아키텍처를 위해 프레임워크를 Express에서 NestJS 로 전환했습니다.
인증/인가를 비즈니스 로직과 섞지 않고 @UseGuards를 통해 파이프라인 단계에서 선언적으로 차단했으며, Custom Decorator를 활용해 토큰 추출과 유효성 검사를 깔끔하게 분리했습니다. 의존성 주입(DI)을 통해 모듈 간 결합도를 낮추어 테스트와 확장이 매우 용이한 구조를 완성했습니다.
The Result & Retrospective
"인증은 단순한 문자열 발급이 아니라, 시스템 간의 신뢰 설계다." 이 프로젝트를 관통하는 가장 큰 깨달음이었습니다. JWT라는 문자열을 만들어내는 것은 쉽지만, 그 문자열이 여러 분산 시스템 사이에서 어떻게 신뢰성을 보장하고, 탈취되었을 때 어떻게 통제할 것인지 설계하는 것이 진정한 백엔드 아키텍트의 역할임을 배웠습니다.
Next Step: 더 견고한 시스템을 향하여 현재의 구조에서 만족하지 않고, 트래픽 증가와 보안 고도화를 대비해 다음과 같은 기술적 확장을 구상하고 있습니다.
- DB + Redis 하이브리드 캐싱: 현재 Refresh Token을 RDBMS에서 직접 조회하여 검증하고 있으나, 대규모 트래픽 발생 시 I/O 병목을 방지하기 위해 조회된 토큰을 Redis에 캐싱하는 구조로 개선할 것입니다. (추가적으로 PM2 Cluster 모드를 활용한 인스턴스 스케일아웃 병행)
- Token Rotation 및 재사용 감지: 보안의 완결성을 위해 Refresh Token 갱신 시 기존 토큰을 무효화하는 Rotation 전략과, 만약 무효화된 토큰으로 다시 갱신 요청이 들어올 경우 탈취로 간주하여 모든 세션을 파기하는 Token Reuse Detection 로직을 추가로 도입할 계획입니다.