Education*
Devops
Architecture
F/B End
B.Chain
Basic
Others
CLOSE
Search For:
Search
BY TAGS
linux
HTTP
golang
flutter
java
fintech
개발환경
kubernetes
network
Docker
devops
database
tutorial
cli
분산시스템
www
블록체인
AWS
system admin
bigdata
보안
금융
msa
mysql
redis
Linux command
dns
javascript
CICD
VPC
FILESYSTEM
S3
NGINX
TCP/IP
ZOOKEEPER
NOSQL
IAC
CLOUD
TERRAFORM
logging
IT용어
Kafka
docker-compose
Dart
NATS를 이용한 멀티 프로덕트 SSO 시스템 구축하기
Recommanded
Free
YOUTUBE Lecture:
<% selectedImage[1] %>
yundream
2023-01-01
2022-12-26
3839
## NAT를 사용하여 비동기 방식으로 SSO 시스템을 구축해보기  MSA(Micro Service Architecture)는 2022년 주요 소프트웨어 아키텍처 트랜드 중 하나다. MSA를 이용하면 필수 기능을 가지는 여러 독립된 컴포넌트로 개발을 하면, 각 팀은 원하는 기술셋을 이용해서 필요한 기능에 집중 할 수 있다. 반면 서비스들이 서로 분리되면서 데이터를 동기화하는데 어려움이 생길 수도 있다. 인증이 대표적인 서비스다. 새로운 애플리케이션이 MSA 구조에 들어왔다고 가정해보자. 이 애플리케이션은 기존에 작동하고 있던 인증/권한 시스템을 사용해야 한다. 즉 인증 서비스는 일종의 **글로벌 서비스**로 독립적으로 작동하는 것이다. 이 인증서비스는 아래의 기능을 가진다. * 사용자의 아이디, 패스워드, MFA를 중앙에서 관리한다. * 사용자별 권한을 관리한다. * SSO(Single Sign On)을 제공한다. * 연결된 모든 응용프로그램에 대해서 어떤 권한을 가지고 있는지 확인한다. SSO 서비스는 구글 사용자 인증 시스템을 보면 쉽게 이해할 수 있을 것이다. 구글은 수많은 서비스들을 제공하는데, 사용자가 일단 로그인 하게 되면, 모든 서비스들에 인증정보가 제공된다. 사용자는 처음 한번의 로그인으로 Gmail, Google Meet, YouTube 등 서로 다른 서비스를 사용 할 수 있다. 또한 각 서비스마다 다른 권한을 설정 할 수도 있다. 이렇게 MSA 환경에서 각 서비스들은 인증정보를 서로 주고 받을 수 있어야 한다. 이 문서에서는 **CNCF NATS**를 이용해서 인증서비스와 다른 서비스들간에 인증정보를 주고 받는 시스템을 구성해볼 것이다. NATS(Network Application Transport Service)는 CNCF에서 개발/배포하는 오픈소스 메시징 시스템이다. 클라우드 네이티브 애플리케이션 및 MSA에서 사용하도록 설계된 경량의 고성능 메시징 시스템이다. NATS는 애플리케이션의 서로 다른 구성 요소간에 통신을 이해서 사용된다. 설치, 사용, 운영이 간단하며 짧은 대기시간, 확장성을 제공하기 때문에 최근 널리 채택되고 있는 추세다. ### 인증 프로세스 검토 [example.com](http://example.com/) 이라는 가상의 회사가 있다고 가정해보자. 이 회사는 Service-A를 비롯한 여러 개의 서비스를 제공하고 있다. 고객 정보는 account.example.com으로 관리를 한다. 각 서비스는 완전히 분리되어 있지만 고객 정보는 account.example.com에서 통합관리를 하는 구조다. 로그인하지 않은 유저가 방문할 경우, 서비스는 [account.example.com](http://account.example.com/) 으로 유저를 **redirection** 한다. 유저는 [account.example.com](http://account.example.com/) 페이지에서 아이디, 패스워드를 입력하여 로그인을 하고 세션(Session)을 발급받는다. 유저는 myService의 서비스에 접근할 때마다 세션을 제공하는데, 서비스는 이 세션이 유효한지 판단을 해야한다. 따라서 각 서비스는 독자적인 세션관리 기능을 가지고 있어야 한다. 아래 다이어그램은 로그인 프로세스를 묘사하고 있다.  마지막으로 Service-A에 session이 저장되면, 유저는 session을 제출하는 것으로 계속해서 서비스를 사용 할 수 있다. 이제 유저는 로그인 필요 없이 [example.com](http://example.com/)의 다른 서비스도 사용 할 수 있다. 유저 경험측면에서 문제는 없지만 session이 각 서비스 local에 저장되면 이후로는 세션정보가 업데이트되지 않는 문제가 생긴다. ### 세션정보의 동기화 세션이 서비스 로컬에 한번 저장되면, 유저는 서비스를 계속해서 이용 할 수 있다. 그런데, 만약 유저가 Account 페이지에서 로그아웃을 하면 어떻게 될까 ? 인증서비스가 분리되어 있기 때문에, Service-A는 로그아웃 사실을 알 수 없고 결국 **Service-A 의 세션이 만료될 때까지** 서비스를 사용 할 수 있게 된다. 사용자 입장에서 로그아웃을 했는데 서비스를 계속 사용할 수 있다면, 서비스를 신뢰할 수 없을 것이다. 이 문제를 해결하는 간단한 방법은 "세션정보를 동기화"하는 것이다. 인증서버에서 로그아웃을 하면, 다른 서비스도 이 사실을 알 수 있도록 하는 것이다. 아래와 같이 프로세스를 바꿔보자.  사용자가 Account 서비스를 이용해서 Service-A 로그아웃을 하면 Account에서 Service-A의 로그아웃 API를 호출한다. LogOut 호출을 받은 Service-A는 로컬 세션을 삭제한다. 세션정보를 동기화 하겠다는 이 아이디어는 아주 간단하고 직관적이다. 하지만 동기적으로 처리해야하는게 마음에 들지 않는다. 비동기적으로 처리하는 방법을 살펴보자. ### 메시지큐를 이용한 비동기적 방식 이 문서에서는 메시지큐를 이용해서 비동기적으로 로그아웃 이벤트를 전달 할 것이다. 동기적 방식으로 이벤트를 전달하는 것과 어떤 차이가 있는지 알아보고 장/단점을 살펴보도록 하자. 동기적으로 이벤트를 전달하는 프로세스는 다음과 같다. 1. 유저가 인증 서버에서 로그아웃을 한다. 2. 인증 서버는 Service-A에 로그아웃 했음을 알린다. 이를 위해서 Service-A는 로그아웃 이벤트를 받을 API를 가지고 있어야 한다. 동기적 방식은 직관적이고 단순하기는 하지만 인증 서버는 인증을 필요로 하는 모든 서버에 세션정보가 변경됐다는 것을 알려줘야 하는 문제가 있다. 이 시나리오에서 account service를 이용하는 독립적인 여러 서비스가 있으며 계속 추가 될 수 있다. 아래와 같이 구조를 바꾸기로 했다.  Message Queue를 이용해서 PUB/SUB 채널을 구성한다. 그리고 Account event를 주고 받기 위한 TOPIC을 생성한다. 만약 유저가 Product A를 로그아웃한다면 Account Service는 이 Event를 게시하게 된다. Product A는 이 Event를 받아서 세션을 삭제하면 된다. Message Queue를 이용해서 프로세스를 다시 정의해보자.  1. 유저가 Account 서비스로 Logout 한다. 2. Account는 Message Queue의 session Topic에 logout event를 publish 한다. 3. Service-A와 Service-B는 session Topic에서 logout event를 subscribe 한다. 4. Service-A와 Service-B는 local session을 삭제한다. 위의 시나리오는 모든 서비스가 Logout 하는 경우를 가정했지만 특정 서비스만 로그아웃 하도록 설정 할 수도 있을 것이다. ### Topic 구성 Topic은 아래와 같이 구성했다.  session.service.service-name 의 계층적 구조를 가진다. 만약 모든 서비스에 logout 이벤트를 보내고 싶다면 session.service.* 로 msg를 전송하면 된다. ### Message 메시지는 JSON 으로 전달하기로 했다. 세션 아이디와 세션상태를 전송하도록 했다. ```json { "id":"my-session-13en8adneg", "status": "close" } ``` ## 예제 NATS Server를 이용해서 구현해보기로 했다. docker를 이용해서 nats 서버를 실행한다. ```bash $ docker run -d --name nats-main -p 4222:4222 -p 6222:6222 -p 8222:8222 nats ``` 테스트를 위해서 nats cli도 설치했다. nats cli를 이용해서 session message를 publish 할 계획이다. [nats-io/natscli](https://github.com/nats-io/natscli) 에서 설치하자. ```shell $ go install github.com/nats-io/natscli/nats@latest ``` 아래는 subscribe를 위한 테스트 애플리케이션이다. 애플리케이션 이름은 session_test 로 했다. ```go package main import ( "encoding/json" "flag" "fmt" "log" "sync" "github.com/nats-io/nats.go" ) type session struct { Id string `json:"id"` Status string `json:"status"` } func main() { var wg sync.WaitGroup wg.Add(1) serviceName := flag.String("name", "service-a", "service name") flag.Parse() sessionName := fmt.Sprintf("session.%s", *serviceName) fmt.Println("Session Name : ", sessionName) nc, err := nats.Connect(nats.DefaultURL) if err != nil { log.Fatal(err) } defer nc.Close() nc.Subscribe(sessionName, func(m *nats.Msg) { sessionStatus := session{} json.Unmarshal(m.Data, &sessionStatus) fmt.Println("id : ", sessionStatus.Id) fmt.Println("status : ", sessionStatus.Status) }) wg.Wait() } ``` 애플리케이션을 실행해보자. ```shell $ ./session --name=service-a $ ./session --name=service-b ``` nats cli를 이용해서 테스트를 했다. ```shell $ nats pub session.service-a < session.json ``` session.json 의 내용은 아래와 같다. ```json { "id":"12345", "status": "close" } ``` ### 정리 이렇게 NATS를 이용해서 비동기적으로 서비스간 세션메시지를 주고 받는 것을 성공적으로 테스트했다. NATS는 원래 Ruby로 개발되었으며 초당 150K 정도의 메시지 전송 성능을 달성했다. 지금은 Go로 재작성됐으며 초당 800만~1100만 개의 터무니 없는 메시지를 처리 할 수 있을 정도로 확장됐다. 클라우드 네티이브, MSA 환경을 위한 메시지 솔류션을 찾고 있다면 NATS를 고려해보는 것도 좋을 것이다. NATS에 대해서 궁금한 점이 있다면 [CNCF NATS - Joinc](https://www.joinc.co.kr/w/CNCF_NATS) 문서를 참고하자.
Recent Posts
vLLM을 이용해서 오픈소스 LLM 서비스 구축하기
Vertex Gemini 기반 AI 에이전트 개발 06. LLM Native Application 개발
최신 경량 LLM Gemma 3 테스트
MLOps with Joinc - Kubeflow 설치
Vertex Gemini 기반 AI 에이전트 개발 05. 첫 번째 LLM 애플리케이션 개발
LLama-3.2-Vision 테스트
Vertex Gemini 기반 AI 에이전트 개발 04. 프롬프트 엔지니어링
Vertex Gemini 기반 AI 에이전트 개발 03. Vertex AI Gemini 둘러보기
Vertex Gemini 기반 AI 에이전트 개발 02. 생성 AI에 대해서
Vertex Gemini 기반 AI 에이전트 개발 01. 소개
Archive Posts
Tags
distribute
messaging
msa
분산시스템
Copyrights © -
Joinc
, All Rights Reserved.
Inherited From -
Yundream
Rebranded By -
Joonphil
Recent Posts
Archive Posts
Tags