이번에 개인 프로젝트를 진행하면서 로그인 시 이메일 인증과 JWT를 이용한 로그인 기능을 구현했습니다. 이메일 인증 코드, access token 재발급을 위한 refresh token 둘다 서버에서 데이터를 저장해야 합니다.
따라서 처음에는 둘다 HttpSession에 저장해 사용하도록 기능을 구현하였으나, 그렇게 되면 JWT의 무상태성이라는 특징을 활용하지 못해 세션으로 로그인하는 것과 같다는 생각을 하게되어 Redis를 도입해 두 데이터를 저장하기로 했습니다.
프로젝트에 도입하기에 앞서 간단하게 Redis에 대해 살펴보았습니다.
Redis(Remote Dictionary Server)는 'key-value' 구조의 비정형 데이터를 저장하고 관리하는 비관계형 데이터베이스 관리 시스템으로입니다.
영어 뜻을 해석하면 다수의 서버를 사용하는 분산 환경의 서버가 공통으로 사용할 수 있는 해시 테이블로 간단하게 생각할 수 있습니다.
Redis는 인메모리 데이터 저장소로 백업을 제외한 모든 데이터를 RAM에 저장하기 때문입니다.
백업, 스냅샷을 제외한 모든 데이터를 RAM에 저장합니다.
단일 Thread로 모든 task를 처리합니다.
다중 노드에 데이터를 분산 저장할 수 있어 안정성과 고가용성을 제공합니다.
인메모리의 특징으로 주로 휘발성 데이터를 저장하지만, RDB와 AOF(Append only File) 옵션을 통해 데이터를 영속적으로 관리 가능합니다.
데이터를 메모리에 저장하기 때문에 매우 빠른 읽기, 쓰기 속도를 제공합니다.
Data Type 지원
다양한 클라이언트 라이브러리 지원
Redis는 주로 cache로 사용되지만 안정적인 캐시 서버 운영을 위해 데이터 영속성을 위한 옵션도 제공합니다.
특정 시간에 스냅샷을 생성해 장애 복구나 캐시 복제 시에 사용합니다.
스냅샷은 특성상 스냅샷 저장 이전의 데이터는 손실될 가능성이 있고, 스냅샷 생성 중에는 레디스의 성능 저하가 발생하게 됩니다.
모든 write 작업을 로그로 저장하는 기술입니다.
데이터 손실 위헙은 적지만, 장애 복구시 로그에 관한 write 작업을 다시 적용하기 때문에 RDB보다 느리다는 특징이 있습니다.
Redis는 주로 Cache로 사용된다고 하여 이에 대해 자세히 알아보겠습니다.
캐싱(Caching)은 데이터를 빠르게 읽고 처리하기 위해 임시로 저장하는 기술을 의미하며, 이때 사용되는 임시 저장소가 Cache 입니다.
Cache Hit
캐시 서버에 특정 키를 가진 캐시 요청 시 정상적인 응답을 반환
즉, 캐시 데이터가 존재함을 의미합니다.
Cache Miss
키가 잘못 되었거나 해당 데이터가 이미 만료되었을 경우
프로젝트에 Redis를 설정하기에 앞서 docker로 redis를 먼저 실행시켜 주었습니다.
RedisTemplate을 활용해 redis에 데이터를 입력하고 조회합니다.
CrudRepository로 JPA와 같이 redis에 저장할 수도 있습니다.
https://docs.spring.io/spring-data/redis/docs/2.3.3.RELEASE/reference/html/#redis.repositories
이메일 인증 시 흐름은 다음과 같이 만들었습니다.
redis를 활용해 저장 데이터에 만료 시간을 설정해주어 정해진 시간동안 이메일 인증이 가능하도록 도입했습니다.
로그아웃하면 access token을 사용할 수 없어야 합니다.
따라서 사용하지 못하게할 access token을 남은 만료 시간동안 redis에 저장합니다.
access token은 redis에 Blacklist 역할로 등록하고 refresh token은 재발급에 사용될 수 없게 redis에서 삭제합니다.
JwtToken 인증 필터에서 access token을 갖고 있다면 redis에 blacklist 값으로 token을 갖고 있는지 확인해 갖고 있다면 예외를 발생시킵니다.
위와 같이 Redis를 활용해 인증코드, JWT 토큰을 통한 인증 및 로그인 기능을 구현했습니다. redis의 만료 시간 설정으로 DB에 데이터를 저장하지 않고 캐싱 기능을 통해 빠르게 데이터를 조회할 수 있습니다.
이후 redis로 분산 락을 이용할 수 있으면 적용해보려 합니다.
Redis 부분은 인프런의 강의를 보고 작성되었습니다.
https://www.inflearn.com/course/%EC%8B%A4%EC%A0%84-redis-%ED%99%9C%EC%9A%A9/dashboard