Spring Boot 프로젝트에 Redis 적용

유호빈·2024년 4월 23일
0

이번에 개인 프로젝트를 진행하면서 로그인 시 이메일 인증과 JWT를 이용한 로그인 기능을 구현했습니다. 이메일 인증 코드, access token 재발급을 위한 refresh token 둘다 서버에서 데이터를 저장해야 합니다.

따라서 처음에는 둘다 HttpSession에 저장해 사용하도록 기능을 구현하였으나, 그렇게 되면 JWT의 무상태성이라는 특징을 활용하지 못해 세션으로 로그인하는 것과 같다는 생각을 하게되어 Redis를 도입해 두 데이터를 저장하기로 했습니다.

프로젝트에 도입하기에 앞서 간단하게 Redis에 대해 살펴보았습니다.

Redis

1. Redis란?

Redis(Remote Dictionary Server)는 'key-value' 구조의 비정형 데이터를 저장하고 관리하는 비관계형 데이터베이스 관리 시스템으로입니다.
영어 뜻을 해석하면 다수의 서버를 사용하는 분산 환경의 서버가 공통으로 사용할 수 있는 해시 테이블로 간단하게 생각할 수 있습니다.

Redis는 인메모리 데이터 저장소로 백업을 제외한 모든 데이터를 RAM에 저장하기 때문입니다.

2. Redis의 특징과 장점

특징

  1. In-Memory

백업, 스냅샷을 제외한 모든 데이터를 RAM에 저장합니다.

  1. Single Threaded

단일 Thread로 모든 task를 처리합니다.

  1. Cluster Mode

다중 노드에 데이터를 분산 저장할 수 있어 안정성과 고가용성을 제공합니다.

  1. Persistence

인메모리의 특징으로 주로 휘발성 데이터를 저장하지만, RDB와 AOF(Append only File) 옵션을 통해 데이터를 영속적으로 관리 가능합니다.

  1. Pub/Sub 지원

장점

  1. 높은 성능

데이터를 메모리에 저장하기 때문에 매우 빠른 읽기, 쓰기 속도를 제공합니다.

  1. Data Type 지원

  2. 다양한 클라이언트 라이브러리 지원


3. Redis 영속성 옵션

Redis는 주로 cache로 사용되지만 안정적인 캐시 서버 운영을 위해 데이터 영속성을 위한 옵션도 제공합니다.

  • RDB (Redis Database)

특정 시간에 스냅샷을 생성해 장애 복구나 캐시 복제 시에 사용합니다.

스냅샷은 특성상 스냅샷 저장 이전의 데이터는 손실될 가능성이 있고, 스냅샷 생성 중에는 레디스의 성능 저하가 발생하게 됩니다.

  • AOF (Append Only File)

모든 write 작업을 로그로 저장하는 기술입니다.

데이터 손실 위헙은 적지만, 장애 복구시 로그에 관한 write 작업을 다시 적용하기 때문에 RDB보다 느리다는 특징이 있습니다.

4. Caching

Redis는 주로 Cache로 사용된다고 하여 이에 대해 자세히 알아보겠습니다.

캐싱(Caching)은 데이터를 빠르게 읽고 처리하기 위해 임시로 저장하는 기술을 의미하며, 이때 사용되는 임시 저장소가 Cache 입니다.

  • Cache Hit
    캐시 서버에 특정 키를 가진 캐시 요청 시 정상적인 응답을 반환
    즉, 캐시 데이터가 존재함을 의미합니다.

  • Cache Miss
    키가 잘못 되었거나 해당 데이터가 이미 만료되었을 경우

프로젝트에 도입

Redis 설정

프로젝트에 Redis를 설정하기에 앞서 docker로 redis를 먼저 실행시켜 주었습니다.

application.yml

Redis Config 파일

Redis Service

RedisTemplate을 활용해 redis에 데이터를 입력하고 조회합니다.

CrudRepository로 JPA와 같이 redis에 저장할 수도 있습니다.

https://docs.spring.io/spring-data/redis/docs/2.3.3.RELEASE/reference/html/#redis.repositories

1. 이메일 인증

이메일 인증 시 흐름은 다음과 같이 만들었습니다.

  1. 유저가 이메일을 입력하면 이메일로 인증 코드를 발송하고 key:value로 이메일과 인증 코드를 redis에 저장합니다.

  1. 유저가 인증 코드를 입력하면 redis에서 이메일 값을 조회해 인증 코드와 비교하고 값이 일치하면 이메일, true라는 값으로 redis에 저장합니다.

  1. 회원가입 시 redis에서 이메일로 조회해 값이 true로 저장되어 있으면 회원가입을 진행합니다.

redis를 활용해 저장 데이터에 만료 시간을 설정해주어 정해진 시간동안 이메일 인증이 가능하도록 도입했습니다.

2. 로그인 시 JWT 토큰 사용

  1. 회원이 로그인을 진행하면 access token과 refresh token을 발행합니다.
    이때, 회원을 식별할 수 있는 값과 refresh token을 redis에 저장합니다.

  1. access token 만료 시 reissue api로 refresh token을 보내 redis에 저장된 refresh 토큰과 값을 비교합니다.
    refresh token이 redis에 저장된 값과 같으면 access token을 재발급해 보내줍니다.

3. 로그아웃 시 Redis를 Blacklist로 활용

로그아웃하면 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

profile
시작하자

0개의 댓글