한화시스템 SW BEYOND CAMP 22기 12주차 회고록

chanjin·2026년 1월 18일

1. MSA 구조에서의 인증/인가 로직 구현

MSA에서 인증을 처리하는 방식은 크게 완전 재검증 방식과 신뢰 기반 방식으로 나뉜다. 이번 학습에서는 성능과 관리 효율성을 위해 신뢰 기반 방식을 채택하여 구현했다.

1) 인증 전략 비교

완전 재검증 방식 (Defense in Depth)

  • 방어 심층(Defense in Depth) 전략: 각 서비스가 독자적으로 JWT 토큰을 검증함으로써, 만약 API Gateway를 우회하여 직접 접근하는 요청이 발생할 경우에도 추가적인 보안 검증이 이루어진다. 이로써 서비스 간의 보안 취약점을 줄일 수 있다.
  • 중복 코드 발생: 서비스마다 동일한 JWT 토큰 검증 로직을 구현하게 되므로, 코드 중복이 발생할 수 있다. 이 경우 공통 라이브러리로 분리하여 관리할 수 있으나, 각 서비스가 독립적으로 해당 로직을 가져야 한다.
  • 성능 부하: 각 요청마다 모든 서비스에서 JWT 토큰 전체를 재검증할 경우, 불필요한 부하가 발생할 가능성이 있다. 특히 트래픽이 많은 서비스에서는 토큰 재검증이 성능에 영향을 줄 수 있다.
  • 보안의 완전성: JWT 토큰이 만료되었거나 변조된 경우 즉시 감지할 수 있으므로, 보안상의 완전성을 보장할 수 있다.

신뢰 기반 방식 (Trusted Header)

  • 코드 중복 감소: API Gateway에서 한 번 검증된 정보를 각 서비스에 전달하므로, 개별 서비스에서 JWT 토큰 전체를 재검증할 필요가 없다. 이로써 코드 중복을 줄이고, 각 서비스의 구현이 간소화된다.
  • 일관된 보안 모델 유지: 모든 내부 서비스가 동일한 헤더 기반의 인증 정보를 활용하여 SecurityContext를 구성하므로, 보안 모델이 일관되게 유지된다. 각 서비스는 Gateway가 전달한 정보만을 신뢰하고 인가 로직을 실행하게 된다.
  • 성능 향상: 매번 모든 서비스에서 JWT 토큰 전체를 재검증하지 않아도 되므로, 시스템 부하가 감소하고 성능이 향상된다.
  • 보안 취약점 고려: API Gateway의 검증 로직에 문제가 발생하거나, Gateway 외부로부터의 접근이 허용되는 경우 보안 취약점이 발생할 수 있다. 따라서 Gateway의 보안이 가장 중요하며, 내부 서비스는 기본적으로 Pre-Authentication 방식(예, 헤더 정보를 기반으로 SecurityContext를 구성하는 필터)을 적용하여 최소한의 보안을 유지하는 것이 바람직하다.

장점 : 코드 중복 감소, 성능 향상, 일관된 보안 모델 유지.

2) 구현 변경 사항 (User Service & Gateway)

기존 Monolithic 또는 개별 인증 방식에서 Gateway 중심 인증으로 변경하며 다음과 같은 코드 수정이 이루어졌다.

API Gateway : JWT 유효성 검증 및 정보 추출(Parsing) 후 Request Header에 추가.

User Service (Spring Security)

  • 삭제: JwtAuthenticationFilter, CustomUserDetailsService (더 이상 DB 조회 불필요).

  • 추가: HeaderAuthenticationFilter (헤더 값을 읽어 PreAuthenticatedAuthenticationToken 생성).

Controller : @AuthenticationPrincipal을 사용해 userId를 바로 주입받도록 변경.

Eureka Client : 서비스 기동 시 Eureka Server에 등록되어 Gateway가 로드밸런싱 할 수 있도록 설정.

3) 서비스 간 통신 (Client → Gateway → Service)

Client: JWT를 담아 Gateway로 요청.

Gateway: 토큰 검증 후 X-User-Id 헤더 추가하여 라우팅.

Service: 헤더 정보를 바탕으로 인증 처리 후 비즈니스 로직 수행.


2. 서비스 인스턴스 간 통신 방법

  • Discovery Client: 직접 인스턴스 리스트를 조회하여 호출. (URL 생성 등 개발자 책임이 큼)

  • RestTemplate (@LoadBalanced): URL을 추상화하여 호출하지만, 여전히 코드가 길어질 수 있음.

  • Feign Client (@FeignClient) : 인터페이스 선언만으로 구현 가능

    Spring MVC 어노테이션(@RequestMapping)을 그대로 사용 가능하여 가독성과 생산성이 높음.

    예시) Order Service에서 User Service의 등급 조회 API를 마치 로컬 메서드처럼 호출.


3. 좋은 MSA Application을 개발하기 위한 7가지 요소

  1. REST API 설계: 표준화된 인터페이스(Swagger 활용), 자원 중심 설계, 버전 관리.

  2. Gateway 설정: 보안, 로드 밸런싱, 인증/인가 집중 처리, 요청 라우팅.

  3. 구성 외부화: 환경별 설정 분리 및 중앙 관리.

  4. 모니터링: 데이터 수집(Prometheus), 시각화(Grafana), 경고 시스템.

  5. 내결함성 (Resilience): 장애 전파 방지(Circuit Breaker), 대체 로직(Fallback).

  6. 로깅 및 분산 추적: 중앙 집중식 로그 관리, Zipkin 등을 통한 트랜잭션 추적.

  7. CI/CD: 자동화 파이프라인 및 테스트 검증.



이번주 배운 것

이번주는 프로젝트 기간이라 배운것은 크게 없고 msa 배운 내용을 더 심화적으로 배웠다!
이론을 제대로 이해하기 전에 프로젝트에서 실제로 써보고 느꼈지만 아직 이론적으로는 많이 부족한 것 같아서 추가적으로 시간을 갖고 공부해야겠다!




이번주 공부 한 것

[Side Project] Spring Boot 투두 리스트 만들기 (TodayMemo) : 회고록

1. 프로젝트 개요

데이터의 흐름(Controller -> Service -> Repository -> DB)을 스스로 밑바닥부터 구현해보기 위해 시작한 사이드 프로젝트였다. 거창한 기능보다는 ai 의존도를 줄이면서 모르는건 구글링하고 최대한 생각해보고 코드를 직접 작성해보고 싶어서 시작했다.

프로젝트명: TodayMemo (나만의 할 일 메모장)
소요 시간: 약 3시간
기술 스택: Spring Boot 3.x, Java 17, JPA(Spring Data JPA), MariaDB, Thymeleaf

2. 개발 과정 & 핵심 배움

  1. Entity 설계 : 디테일의 중요성
    처음엔 막연하게 int completed 같은 필드를 생각했지만, JPA Entity로 구현하면서 명확한 타입(Boolean, LocalDateTime)의 중요성을 배웠다. 특히 memoTitle처럼 중복된 접두사를 제거하고 title로 깔끔하게 리팩토링하는 과정을 통해 Clean Code에 대해 고민해볼 수 있었다.

  2. Service Layer 구현 : 비즈니스 로직의 분리
    컨트롤러에 모든 로직을 때려 넣는 게 아니라, Service 계층을 따로 두어 역할을 분리했다. 가장 기억에 남은건 Update(수정) 기능이었다.

@Transactional
public TodoEntity updateTodo(...) {
    TodoEntity todo = repository.findById(id).orElseThrow(...);
    todo.setTitle(newTitle); 
    // repository.save(todo) 호출 안 함!
}

Dirty Checking을 이론적으로는 나름 잘 알고있다고 생각했고 수업시간에 강사님과 같이 코드도 써보면서 혼자 사이드 프로젝트를 하면서 쉽게쉽게 할 수 있을거라고 생각했는데 제일 오래 막히고 생각해본 부분이였다.

3. 트러블 슈팅 (Troubleshooting)

문제 : Port 8080 was already in use

원인 분석: 아까 실행하다가 에러 나서 멈춘 줄 알았던 서버가, 실은 백그라운드에서 계속 실행중이였다. 에러코드를 분명히 읽었고, 어떻게 해결하는지도 잘 아는데 왜 그렇게 고민하고 당황했는지 모르겠다 ㅠ

해결 : 포트번호를 8081로 변경하여 시작하니 손쉽게 해결했다...!

느낀점

이번 프로젝트때 ai에게 의존을 너무 많이해서 ai의존도를 줄이고자 시작한 프로젝트였다.
주제가 어렵지 않아도 강사님과 ai 도움 없이 db 생성부터 직접 혼자 하는 과정이 쉽지 않을줄은 알았는데 생각보다 많이 어려웠다.
이미 다 아는 개념이였지만 직접 하나하나 생각하면서 쓰는건 또 다른 영역이라는 생각이 들었고, 1~2주에 한번씩은 주제 바꿔가면서 해보고 싶다! 오늘도 결국 ai를 사용하긴 했지만 그래도 내가 직접 고민하고 작성한게 훨씬 많았어서 그런가 엄청 뿌듯했다!!!
이번주는 수업시간에 배운 개념보단 프로젝트를 복기하고 사이드 프로젝트도 해보면서 주말을 보냈는데 생각보다 더 의미있는 주말이였던것 같아서 뿌듯하다!
그동안 열심히만 한 것 같고 스스로 잘했다고 느낄만한 부분이 없어서 많이 속상했는지만 (조금 울었움🥲) 아직까진 초심을 잃지 않고 열심히 노력하니까 수료하기 전엔 스스로 내가 잘해졌다고 느껴질 수 있도록 더 노력해야겠다!
그리구 백엔드 지필평가 생각보다 높은 점수가 나와서 뿌듯했다 우하하하하하!😆😆

profile
찬지니에오

0개의 댓글