배경
모노레포 전환 후 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-security 모듈 제거 → 인증 로직이 Gateway 한 곳에 집중
codin-common 경량화 → Spring Security 비의존, 필요한 서비스만 starter 선택
- nginx.conf 간소화 → 백엔드 라우팅 관리에서 해방
- 라우팅/인증 설정을 코드/yml로 관리 (버전관리, 코드리뷰, 테스트 가능)
- Spring Security / OAuth2와 네이티브 통합
X-Forwarded-* 헤더 자동 처리
- 향후 Rate Limiting, Circuit Breaker 등 확장 가능
트레이드오프
- JVM 서비스 추가 (메모리 ~256MB)
- 추가 네트워크 홉으로 약간의 레이턴시
- 배포/관리 대상 서비스 +1
배경
모노레포 전환 후 nginx에서 마이크로서비스별 라우팅을 관리하고 있으나, 서비스가 늘어남에 따라 nginx.conf의 복잡도가 증가하고 있습니다.
특히 OAuth2 플로우에서 다음과 같은 문제가 반복적으로 발생합니다:
/api) strip/추가에 따른 라우팅 불일치X-Forwarded-Proto미전파로 인한http/https문제아키텍처 변경
AS-IS
TO-BE (현재 완료 상태)
현재 모듈 구조
codin-gateway(완료)X-User-Id,X-User-Role,X-User-Email헤더를 downstream에 전달public-paths: JWT 완전 스킵 (/api/auth/**,/api/oauth2/**등)public-api-paths: 비인증 fallback 허용 (/api/posts/{postId}등)codin-common(완료 — POJO only)UserRole(enum),SecurityErrorCode,SecurityException,JwtExceptioncodin-gateway-header-starter(완료 — 신규)codin-common에서 Security 관련 클래스 분리inu.codin.security.*SecurityUtil,TokenUserDetails,GatewayHeaderAuthenticationFilter,ExceptionHandlerFilter,CustomAccessDeniedHandler,GatewayHeaderFeignInterceptor,GatewayHeaderSecurityConfigcodin-auth(완료)codin-common만 의존@Order(1)oauth2Chain +@Order(2)defaultChain)SecurityUtil,@PreAuthorize사용 없음 → starter 불필요 확인 완료codin-security(삭제 완료)codin-gateway+codin-gateway-header-starter로 이관다운스트림 서비스 (완료)
codin-common+codin-gateway-header-starter의존@PreAuthorize메서드 레벨로 유지의존성 그래프
보안 아키텍처 역할 분담
@PreAuthorize메서드 레벨 권한 체크public-paths/public-api-paths→ URL-level 인증 정책permitAll()→ "Gateway를 신뢰, HTTP 필터에서 재검증 안 함"의 의미 (보안 무시가 아님)@PreAuthorize→ 실제 비즈니스 인가 체크작업 목록
codin-gateway모듈 생성 + Spring Cloud Gateway 의존성 설정codin-security의 JWT 검증/인가 로직을 GatewayGatewayFilter로 변환X-User-Id,X-User-Role,X-User-Email헤더 주입 필터 구현codin-common경량화 — Spring Security 의존 제거, POJO onlycodin-gateway-header-starter신규 모듈 생성 — Security 관련 클래스 분리codin-security→codin-gateway-header-starter마이그레이션 (48개 파일 import 교체)codin-authSecurityConfig 정리 — defaultChain 추가, starter 불필요 확인codin-security모듈 삭제./gradlew test실행으로 런타임 동작 확인기대 효과
codin-security모듈 제거 → 인증 로직이 Gateway 한 곳에 집중codin-common경량화 → Spring Security 비의존, 필요한 서비스만 starter 선택X-Forwarded-*헤더 자동 처리트레이드오프