-
Firebase 에서 OAuth2 , JWT 로 전환기(1)Project/TravelFeelDog 2023. 8. 8. 19:46
도입 배경
기존의 프로젝트는 웹과 앱 모두를 지원을 하는 상황 , 유저의 로그인 인증여부를 firebase Auth 서비스를 사용하였다.
당시 한달이라는 개발 기간안에 Spring Security 까지 다룰 여력이 부족하여 Firebase Auth 를 사용한 시스템을 이용했다.
Firebase Authentication 의경우 이메일 존재여부, 중복여부, 연락처 인증 등 다양한 기능을 지원하니 여력이 부족하면 사용하는 것을 추천한다.
대략적인 흐름은 다음과 같다.
Client : 안드로이드 모바일 , 리엑트 웹 등
Firebase : Firebase Authentication service
Resource Server : SpringBoot , Node server etc..
클라이언트의 구글 로그인을 통한 리소스 서버 접속 요청시
(클라이언트 서비스에서 구글 로그인 배너를 클릭하는 유저 케이스이다.)
1. 클라이언트가 구글 파이어배이스에 로그인 요청 ,firebase 서버로 부터 (uuid 토큰) 인증 토큰을 반환 받는다.
-> 최초 시도의 경우 sns 인증 화면 , 어떤 메일을 사용하는지 물어보는 화면이 나타난다.
-> 이미 서비스에서 인증한 유저라면 FireBase 로 부터 바로 인증 토큰(UUID)을 전송 받는다.
2. 클라이언트에서 FireBase 로 부터 반환받은 토큰(UUID)를 ResourceServer (스프링 서버)로 로그인 요청을 한다.
( 토큰은 REST API 구조의 Header 에 담는다. )
3 . SpringBoot에서 다음 두가지경우에 맞춰 알맞은 응답 값을 반환한다.
1 .클라이언트의 로그인 요청 정보가 MYSQL과 같은 저장소에 없는경우
2 . 클라이언트의 로그인 요청 정보가 있는 경우
4. 응답 값를 바탕으로 클라이언트의 로그인 페이지에서 회원가입 창으로 이동하거나 홈페이지로 이동한다.
5. 4번에서 회원 가입 페이지로 이동하는 경우 회원가입 정보 + uuid 토큰을 SpringBoot Server 로 전달하고 , SpringBoot 의 회원 가입 응답 완료 반환을 받으면 서비스의 홈 페이지를 이동한다.
위의 방식으로 회원가입 한 후 이후 서비스 관련 api 요청시 해더 Authorization 에 firebase 토큰을 같이 전달하여 서버 자원을 사용한다.
다음 3가지의 문제 상황에 해결책으로 Jwt ,Oauth 2 를 도입 하고자 한다.
- 기간 만료가 없는 토큰을 브라우저에서 보관을 하게되면 보안의 위험이 있다.
- 토큰의 만료 시간을 FireBase Cloud 가 아닌 SpringBoot 에서 변경이 불가능하여 외부시스템의 의존성이 생긴다.
- 토큰의 대한정보를 데이터 베이스의 저장을 하는 위험이 있다.
추가적으로 인증 및 인가를 위한 유저 정보를 관리하기 위하여 Redis 를 사용하여 세션을 관리하고자 한다.
(* redis 를 외부 WAS 와 다른 서버에 구성한다.)
Redis 를 이용하여 로그인 세션을 관리를 하면 다음과 같은 장점이 있다.
global cache 방식
1. 스프링 서버의 문제가 발생시 영향을 "덜" 받을 수 있다.
2. 사용자 증가에 따른 ScaleOut 시 정합성 유지의 이점이 있다.
Redis 를 이용하여 로그인 세션을 관리를 하면 다음과 같은 단점이 있다.
WAS 가 살아있는데 Redis 가 죽으면 세션 캐쉬의 이점을 못받는다 .
Memcached 의 경우 Redis 와 다르게 데이터 타입이 없고 Redis 보다 메모리 오버 해드가 적은 멀티 스레드로 수직적확장을 위하여 사용된다.
사용자 증가에 따른 ScaleOut 을 고려한 설계를 위해 Redis 를 쓰자~
전반적인 개발 프로세스는 다음과 같다 .
1차 목표
1. JWT,OAuth2 를 도입하는 인증 절차를 먼저 구성한다.
2. Redis 를 사용하여 사용자의 세션 정보를 저장 하고 , 클라이언트 사이드에 어세스 토큰을 전달하여 브라우저에서 관리를 하게 한다. ,Thread safe 를 생각하여 Lettuce 를 사용한다.
2차 목표 | 사용자가 몰리는 상황을 가정
1 . scale out 을 고민 - 빠른 스케일 아웃을 위한 k8s 와 redis cluster 의 학습이 선행 되어야 할 것 같다
2. 인증을 위한 서버를 따로 분리
-> 트랜잭션의 문제가 생길 수 있어 kafka 를 사용한 사가 트랜잭션 분산 패턴을 적용 할 것 같다.
3차 목표 | 보안 & 운영
여러 인스턴스를 관리 해야함으로 설정을 분리해야한다. : 스프링 클라우드 컨피그를 도입
보안을 위하여 적용할 사항들 : private subnet 에 인증서버를 구성 , public NatGateway 로 igw 및 subnet 연결 등
'Project > TravelFeelDog' 카테고리의 다른 글
SpringBoot MySql bulkInsert 도입기 (0) 2023.08.30 Service Layer 에 읽기 쓰기 분리기 (0) 2023.08.10 yml 환경 변수 설정 (0) 2023.07.18 경로 에러 추가 하기 (0) 2023.07.18 AWS s3 이미지 업로더 분리기 (feat. @Configurration 활용) (0) 2023.07.14