일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- SSR
- 반공변성
- 리터럴 타입
- Promise
- useAppDispatch
- 인터섹션
- 인증/인가
- async/await
- Jest
- webpack
- 공변성
- 태그된 유니온
- 투포인터
- autosize
- RTK Query
- map
- CI/CD
- MSA
- app router
- ESlint
- dfs
- recoil
- 타입 좁히기
- CORS
- tailwind
- 결정 알고리즘
- 무한 스크롤
- 호이스팅
- React
- TS
Archives
- Today
- Total
짧은코딩
MSA에서 백엔드는 어떻게 인증/인가를 할까 본문
반응형
Spring Boot로 회원가입/로그인을 만들고, Nest로 블로그 서비스 CRUD를 만들다 보니까 들은 생각이 있었다.
MSA는 서로 인증/인가를 어떻게 할까? 처음에는 Spring Boot로 만든 인증/인가 서비스에서 모든 처리를 하면 되겠다고 생각을 했다. 하지만 이 방식은 뭔가 허술하다는 것을 느꼇고, MSA에서 인증/인가를 구현하는 방식을 찾아보고 그 중에서 제일 괜찮은 방식을 적용해야 겠다고 생각했다.
1. API 게이트웨이
설명
- API 게이트웨이는 마이크로서비스 아키텍처에서 클라이언트와 백엔드 서비스 사이의 프록시(Proxy) 서버 역할을 하는 핵심 컴포넌트
- 인증/인가 관점에서 게이트웨이는 모든 외부 요청에 대한 단일 진입점(Single Point of Entry)으로 동작하며, 보안 관련 로직을 중앙에서 처리
과정
Step 1: 게이트웨이 필터/미들웨어에서의 인증 처리
- API 게이트웨이는 라우팅 로직을 실행하기 전에, 사전에 정의된 필터 체인(Filter Chain) 또는 미들웨어(Middleware)를 통해 요청을 처리
- 이 필터 중 하나가 인증 필터(Authentication Filter)의 역할을 수행
- 인증 필터의 핵심 로직:
- Authorization 헤더에서 JWT(JSON Web Token)를 추출
- 미리 설정된 Secret Key나 Public Key를 사용하여 토큰의 서명(Signature)을 검증합니다. 서명이 유효하지 않으면, 이 요청은 위조된 것으로 간주
- 토큰의 Payload에 포함된 만료 시간(exp claim)을 현재 시간과 비교하여 토큰이 만료되지 않았는지 확인
- 발급자(iss claim) 등 기타 클레임들이 유효한지 검증
- 만약 위 과정 중 하나라도 실패하면, 게이트웨이는 즉시 401 Unauthorized 또는 403 Forbidden HTTP 상태 코드로 응답하고 요청 처리를 중단
- 이로써 유효하지 않은 트래픽이 내부망으로 유입되는 것을 원천 차단
Step 2: 요청 재구성 및 다운스트림 서비스로 전파
- 인증에 성공하면, 게이트웨이는 다운스트림(내부) 서비스가 신뢰하고 사용할 수 있도록 요청을 재구성
- 헤더 변조/추가:
- 보안을 위해 외부에서 사용된 Authorization 헤더를 제거
- 검증된 JWT의 Payload에서 사용자 식별자(sub claim, 보통 User ID)나 역할(Role) 정보를 추출하여, 신뢰할 수 있는 새로운 내부용 헤더에 담아줌 (예: X-User-ID: 12345, X-User-Roles: ADMIN,USER)
- 이러한 헤더 추가는 다운스트림 서비스가 사용자를 신뢰하고 인가 처리를 쉽게 할 수 있도록 함
Step 3: 라우팅 (Routing)
- 게이트웨이는 요청 경로(예: /orders/**)를 기반으로 사전에 정의된 라우팅 테이블을 참조하여, 이 요청을 처리할 적절한 내부 마이크로서비스(예: order-service)로 프록시(Proxy)
기술적 장점
- 관심사의 분리 (Separation of Concerns)
- 비즈니스 로직을 처리하는 마이크로서비스 코드에서 인증/보안 관련 코드가 완전히 분리
- 서비스 개발자는 보안 라이브러리나 Secret Key 관리에 신경 쓸 필요 없이 비즈니스 기능 개발에 집중
- 중앙 집중화된 보안 관리
- 보안 정책 변경(예: 토큰 만료 시간 변경, 암호화 알고리즘 교체)이 필요할 때, 여러 서비스를 수정할 필요 없이 API 게이트웨이 한 곳만 수정하면 됨
- 보안 경계 형성 (Security Perimeter)
- 외부와 내부 네트워크 사이에 명확한 보안 경계를 만들어, 인증되지 않은 어떤 요청도 내부 시스템에 도달하지 못하게 막는 방화벽 역할을 수행
- 성능 향상
- 다운스트림 서비스들이 매 요청마다 수행해야 할 암호화 검증 작업을 게이트웨이가 대신 처리해주므로, 전체 시스템의 부하를 줄임
2. 내부 JWT(서비스 간(Inter-Service) JWT 인증)
설명
- 이 방식은 외부 사용자를 위한 인증과 별개로, 내부 마이크로서비스끼리 통신할 때 서로의 신원을 확인하기 위해 별도의 JWT를 사용하는 방법
- 결국 클라이언트와 인증/인가 서비스는 또 따로 있어야 함
- 중앙 인증 서비스(Auth Service)가 각 서비스에게 고유한 JWT를 발급하고, 서비스들은 다른 서비스를 호출할 때 이 JWT를 사용해 자신의 신원을 증명
과정
Step 1: 서비스 고유의 JWT 발급 요청 및 수신
- 블로그 서비스(Nest)가 시작될 때, 또는 주기적으로 중앙 인증 서비스(Spring Boot)에 자신의 서비스 이름(예: blog-service)과 같은 식별 정보를 보내 내부 통신용 JWT를 요청
- 인증 서비스는 요청한 서비스의 신원을 확인한 후, 해당 서비스만을 위한 내부용 JWT(Internal JWT)를 발급해 응답
- 이 JWT에는 sub: 'blog-service' 와 같이 서비스의 이름이 포함
- 사용자용 JWT보다 훨씬 짧은 만료 시간(예: 5분, 10분)을 가짐
- 호출 가능한 서비스 목록(aud: ['user-service', 'payment-service']) 등 더 세분화된 권한 정보를 포함할 수 있음
Step 2: 내부 JWT를 이용한 서비스 간 호출
- 이제 블로그 서비스가 특정 유저 정보를 얻기 위해 회원 서비스(Spring Boot)를 호출해야 하는 상황을 가정
- 블로그 서비스는 회원 서비스를 호출할 때, Authorization: Bearer <내부용 JWT> 헤더에 Step 1에서 발급받은 내부용 JWT를 담아 보냄
- 이때 API에서 받은 사용자 정보 헤더(예: X-User-ID: 123)도 함께 전달하여, "내가 블로그 서비스인데, 123번 사용자의 정보를 요청한다"는 의미를 명확히 밝힘
Step 3: 호출받은 서비스에서의 내부 JWT 검증
- 요청을 받은 회원 서비스는 Authorization 헤더의 내부용 JWT를 검증
- 이때 검증은 인증 서비스와 공유된 Secret Key 또는 Public Key를 사용
- JWT가 유효하고, 토큰에 명시된 sub 클레임이 신뢰할 수 있는 서비스(예: blog-service)임이 확인되면 요청을 처리
- 유효하지 않으면 403 Forbidden으로 응답하여 비인가 서비스의 접근을 차단
기술적 장점
- Zero-Trust 네트워크 구현
- "내부망은 안전하다"는 가정을 버리고, 모든 서비스 간 통신에 대해 인증을 강제하여 내부의 잠재적 위협으로부터 시스템을 보호
- 세분화된 접근 제어
- 서비스별로 호출할 수 있는 다른 서비스의 목록을 JWT에 명시하여, A 서비스는 B 서비스만 호출할 수 있고 C 서비스는 호출할 수 없도록 정교한 제어가 가능
- 서비스 신원 명확화
- 어떤 서비스가 요청했는지 명확하게 식별하고 로그로 남길 수 있어, 문제 발생 시 추적 및 디버깅이 용이
- 게이트웨이 의존성 감소
- API 게이트웨이가 모든 것을 처리하는 대신, 각 서비스가 자신의 보안을 일부 책임지는 구조로 분산되어 게이트웨이의 부하를 줄일 수 있음
반응형
'MSA 공부' 카테고리의 다른 글
FE 아키텍처 변경과 이유 with 셸 앱(Sheel App) (2) | 2025.08.06 |
---|---|
Nest, Yarn Berry + WebStorm에서 라이브러리 Not Found 해결 방법 (0) | 2025.07.16 |
인증/인가, Spring Boot 서버 구축 (0) | 2025.07.05 |
MSA 초기 아키텍처 (1) | 2025.06.21 |
Comments