Skip to content

Spring Cloud Gateway 도입 검토 #12

@gisu1102

Description

@gisu1102

배경

모노레포 전환 후 nginx에서 마이크로서비스별 라우팅을 관리하고 있으나, 서비스가 늘어남에 따라 nginx.conf의 복잡도가 증가하고 있습니다.

특히 OAuth2 플로우에서 다음과 같은 문제가 반복적으로 발생합니다:

  • path prefix (/api) strip/추가에 따른 라우팅 불일치
  • X-Forwarded-Proto 미전파로 인한 http/https 문제
  • OAuth2 콜백 경로마다 nginx location 블록 수동 추가 필요
  • 서비스 추가/변경 시 nginx.conf 수정 + 컨테이너 재시작 필요

아키텍처 변경

AS-IS

브라우저 → nginx (SSL + 프론트엔드 + 백엔드 라우팅) → codin-auth / codin-core / ...
                                                        ↑ 각 서비스가 codin-security 모듈 의존

TO-BE (현재 완료 상태)

브라우저 → nginx (SSL + 프론트엔드만)
         → Gateway (라우팅 + JWT 인증)
           → codin-auth (자체 OAuth2, starter 미사용)
           → codin-core / ticketing-api / ticketing-sse / lecture-api
             ↑ codin-gateway-header-starter (헤더 파싱 + Spring Security)
               ↑ codin-common (POJO only, Security 의존 없음)

현재 모듈 구조

codin-gateway (완료)

  • Spring Cloud Gateway 기반 API Gateway
  • JWT 검증 후 X-User-Id, X-User-Role, X-User-Email 헤더를 downstream에 전달
  • 인증 레벨 접근 제어:
    • public-paths: JWT 완전 스킵 (/api/auth/**, /api/oauth2/** 등)
    • public-api-paths: 비인증 fallback 허용 (/api/posts/{postId} 등)
  • X-User-* 헤더 스트리핑 (외부 스푸핑 방지)
  • CORS 설정

codin-common (완료 — POJO only)

  • Spring Security 의존 완전 제거
  • 남은 것: UserRole (enum), SecurityErrorCode, SecurityException, JwtException
  • 공통 유틸: response, exception, entity, config 등

codin-gateway-header-starter (완료 — 신규)

  • codin-common에서 Security 관련 클래스 분리
  • 패키지: inu.codin.security.*
  • 포함: SecurityUtil, TokenUserDetails, GatewayHeaderAuthenticationFilter, ExceptionHandlerFilter, CustomAccessDeniedHandler, GatewayHeaderFeignInterceptor, GatewayHeaderSecurityConfig
  • AutoConfiguration으로 자동 등록
  • 필요한 서비스만 선택적으로 의존

codin-auth (완료)

  • starter 미사용, codin-common만 의존
  • 자체 OAuth2 Security (@Order(1) oauth2Chain + @Order(2) defaultChain)
  • 모든 엔드포인트가 public (토큰 발급/갱신/OAuth2만 담당)
  • SecurityUtil, @PreAuthorize 사용 없음 → starter 불필요 확인 완료

codin-security (삭제 완료)

  • 모든 기능이 codin-gateway + codin-gateway-header-starter로 이관
  • 모듈 제거됨

다운스트림 서비스 (완료)

  • codin-core, ticketing-api, ticketing-sse, lecture-api
  • codin-common + codin-gateway-header-starter 의존
  • 인가: @PreAuthorize 메서드 레벨로 유지

의존성 그래프

codin-common (POJO, Security 없음)
    ↑
codin-gateway-header-starter (Spring Security + 헤더 파싱)
    ↑
codin-core, codin-ticketing-api, codin-ticketing-sse, codin-lecture-api

codin-common (POJO)
    ↑
codin-auth (자체 OAuth2, starter 미사용)

보안 아키텍처 역할 분담

계층 역할 구현
Gateway 인증 (Authentication) JWT 검증, URL-level 접근 제어, 헤더 주입
Downstream 인가 (Authorization) @PreAuthorize 메서드 레벨 권한 체크
  • Gateway의 public-paths / public-api-paths → URL-level 인증 정책
  • Downstream의 permitAll() → "Gateway를 신뢰, HTTP 필터에서 재검증 안 함"의 의미 (보안 무시가 아님)
  • Downstream의 @PreAuthorize → 실제 비즈니스 인가 체크

작업 목록

  • codin-gateway 모듈 생성 + Spring Cloud Gateway 의존성 설정
  • codin-security의 JWT 검증/인가 로직을 Gateway GatewayFilter로 변환
  • CORS 설정 + 공개 경로(permitAll/publicApi) 관리를 Gateway로 이동
  • 5개 서비스 라우트 정의 (auth, core, ticketing-api, ticketing-sse, lecture)
  • JWT 검증 후 X-User-Id, X-User-Role, X-User-Email 헤더 주입 필터 구현
  • codin-common 경량화 — Spring Security 의존 제거, POJO only
  • codin-gateway-header-starter 신규 모듈 생성 — Security 관련 클래스 분리
  • 각 서비스에서 codin-securitycodin-gateway-header-starter 마이그레이션 (48개 파일 import 교체)
  • codin-auth SecurityConfig 정리 — defaultChain 추가, starter 불필요 확인
  • codin-security 모듈 삭제
  • docker-compose.yml에 Gateway 서비스 추가
  • Gateway 배포 워크플로우(CI/CD) 추가
  • nginx 설정 간소화 — 백엔드 라우팅 제거, Gateway 프록시만 유지
  • OAuth2 로그인 플로우 / JWT 인증 / 각 서비스 API 호출 통합 테스트
  • 전체 ./gradlew test 실행으로 런타임 동작 확인

기대 효과

  • codin-security 모듈 제거 → 인증 로직이 Gateway 한 곳에 집중
  • codin-common 경량화 → Spring Security 비의존, 필요한 서비스만 starter 선택
  • nginx.conf 간소화 → 백엔드 라우팅 관리에서 해방
  • 라우팅/인증 설정을 코드/yml로 관리 (버전관리, 코드리뷰, 테스트 가능)
  • Spring Security / OAuth2와 네이티브 통합
  • X-Forwarded-* 헤더 자동 처리
  • 향후 Rate Limiting, Circuit Breaker 등 확장 가능

트레이드오프

  • JVM 서비스 추가 (메모리 ~256MB)
  • 추가 네트워크 홉으로 약간의 레이턴시
  • 배포/관리 대상 서비스 +1

Metadata

Metadata

Assignees

Labels

Type

No fields configured for Task.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions