Spring 7기 프로젝트/플러스 팀 프로젝트

Spring Boot에서 RestTemplate 내부 API 호출 시 JWT 토큰 전달하기

JuNo_12 2025. 7. 11. 12:09

문제 상황

Spring Boot 프로젝트에서 한 도메인이 다른 도메인의 API를 호출할 때 발생할 수 있는 인증 문제를 해결한 경험을 공유하고자 합니다.

 

프로젝트 구조

HotDeal API 서버 (localhost:8080)
├── Stock Domain (재고 관리)
├── Product Domain (상품 관리)  
└── Auth Domain (인증/인가)

 

발생한 문제

재고 관리 API에서 상품 검증을 위해 상품 조회 API를 호출하는 상황에서 에러가 발생했습니다.

 

문제 분석

핵심 문제: RestTemplate을 통한 내부 API 호출 시 원본 요청의 JWT 토큰이 전달되지 않음


해결책 비교

방법 1: 매번 수동으로 토큰 전달

public SearchProductResponse getProduct(Long productId) {
    HttpHeaders headers = new HttpHeaders();
    
    // 현재 요청에서 토큰 가져오기
    String authHeader = getCurrentAuthHeader();
    if (authHeader != null) {
        headers.set("Authorization", authHeader);
    }
    
    HttpEntity<Void> entity = new HttpEntity<>(headers);
    return restTemplate.exchange(url, HttpMethod.GET, entity, SearchProductResponse.class);
}

 

단점:

  • 매번 토큰 전달 코드 작성 필요
  • 코드 중복
  • 실수로 빠뜨릴 가능성

 

방법 2: RestTemplate 인터셉터 (채택)

 

장점:

  • 자동화: 모든 RestTemplate 호출에 자동으로 JWT 토큰 전달
  • DRY 원칙: 코드 중복 제거
  • 실수 방지: 개발자가 토큰 전달을 깜빡할 일 없음
  • 유지보수성: 토큰 전달 로직이 한 곳에 집중
 

동작 과정

sequenceDiagram
    participant Client
    participant StockController
    participant StockService
    participant ProductApiClient
    participant RestTemplate
    participant ProductController

    Client->>StockController: POST /stocks/1/increase (JWT)
    StockController->>StockService: increaseStock()
    StockService->>ProductApiClient: getProduct(1)
    ProductApiClient->>RestTemplate: getForObject()
    RestTemplate->>RestTemplate: 인터셉터가 JWT 토큰 자동 추가
    RestTemplate->>ProductController: GET /products/1 (JWT)
    ProductController-->>RestTemplate: 200 OK
    RestTemplate-->>ProductApiClient: ProductResponse
    ProductApiClient-->>StockService: ProductResponse
    StockService-->>StockController: StockResponse
    StockController-->>Client: 200 OK

추가 고려사항

1. 보안 측면

  • 내부 API 호출에만 적용되므로 보안상 안전
  • 토큰 유효성은 각 도메인에서 개별적으로 검증

2. 성능 측면

  • RequestContextHolder는 ThreadLocal 기반으로 성능 오버헤드 미미
  • 인터셉터 로직이 단순하여 추가 지연 없음

3. 대안 방법들

  • Spring Cloud OpenFeign: 마이크로서비스 간 통신 시 권장
  • 내부 서비스 호출: 같은 애플리케이션 내에서는 직접 서비스 호출 고려
  • API Gateway: 외부에서는 Gateway를 통한 라우팅

 

결론

RestTemplate 인터셉터를 활용하여 JWT 토큰 전달 문제를 깔끔하게 해결했습니다.

  • 모놀리식 아키텍처에서 도메인별로 분리된 API 호출
  • 마이크로서비스 확장 초기 단계에서 임시적인 내부 API 호출
  • 레거시 시스템과의 통신

 

참고 자료