Refresh Token 관리를 위한 Redis 도입기

영광·2025년 7월 30일
0

bucketListProject

목록 보기
4/5
post-thumbnail

Redis를 Refresh Token 저장소로 도입한 이유

이번 프로젝트에서 JWT 인증 구조를 도입하게 되었고, Access Token과 Refresh Token을 함께 사용하는 구조로 전환하게 되었습니다.
Refresh Token은 상대적으로 수명이 길고, 클라이언트가 직접 저장하고 있기에는 보안적인 이슈가 있어 서버측의 저장소가 필요했습니다.
처음에는 현재 사용중인 관계형 DB(PostgreSQL)를 고려했습니다. 사용자의 이메일을 키로 삼아 토큰 값을 저장하고, 만료시간은 별도 필드로 지정하는 방식입니다.
그러나 이 방식은 토큰 저장·검증·삭제 과정에서 불필요하게 DB 트래픽을 유발하고, 만료 처리를 위해 별도의 배치 작업이 필요하다는 단점이 있었습니다.
이 문제를 해결하고자, Redis를 Refresh Token 저장소로 도입하게 되었습니다.

Refresh Token에 대한 자세한 내용은 별도의 포스트에서 다룰 예정입니다.

왜 Redis인가?

Refresh Token은 일반적으로 수명이 길고, 유출 시 보안 사고로 이어질 수 있기 때문에 서버 측에서 안전하고 효율적으로 관리되어야 합니다. 그렇기에 다음과 같은 이유로 Redis를 선택했습니다.

  • 만료 시간 관리: Redis는 TTL(Time to Live)을 지원하여 토큰의 유효기간을 설정하면
    데이터 만료 시간이 지나면 자동으로 삭제됩니다. 이로 인해 별도의 정리 로직을 구현할 필요가 없습니다.
  • 빠른 응답 속도: 데이터를 디스크가 아닌 RAM에 저장하는 인메모리 기반의 저장소이기 때문에 디스크 I/O에 비해 훨씬 빠릅니다. 특히 로그인이나 토큰 재발급 API와 같이 호출 빈도가 높은 API에서 자주 조회되는 키에 대해 캐시 히트가 발생해 빠르게 응답할 수 있어 병목 없이 처리됩니다.
  • 삭제 처리의 단순함: 로그아웃 시 단순히 해당 키를 삭제하는 것만으로 토큰 무효화가 가능해 유지 관리가 쉽습니다.
  • 간단한 구조: 관계형 DB처럼 테이블이나 스키마를 구성할 필요 없이, noSQL 형태로 key를 지정하고 토큰 문자열을 value로 저장하여 사용할 수 있습니다.

이처럼 Redis는 Refresh Token 저장에 필요한 조건들을 대부분 만족시키면서, 시스템 전반의 복잡도를 높이지 않습니다.

관계형 DB를 사용한다면?

사용자의 수가 적은 시스템에서는 id, refreshToken, expiresAt 필드를 가진 테이블을 만들어 사용할 수 있습니다. 하지만 실무 수준에서는 다음과 같은 문제들이 발생할 수 있습니다.

  • 토큰 만료 처리 로직
    RDB(관계형 DB)에는 TTL 개념이 없기 때문에 만료된 토큰을 삭제하기 위한 주기적인 배치 작업 또는 쿼리 조건을 매번 추가해주어야 하기에 관리 포인트가 늘어납니다.
  • 응답 속도 이슈
    로그인 및 토큰 갱신 API는 빈도가 높은 요청입니다. 이때 매번 DB를 읽고 사용한다면 성능 저하가 누적됩니다. 특히 사용자의 수가 많은 서비스일수록 병목이 심해집니다.
  • 불필요한 I/O 비용
    Refresh Token은 일정 시간이 지나면 폐기되는 휘발성 데이터이므로, 이를 영구 저장소에 보관하는 것은 리소스 낭비입니다.

이러한 이유로 Refresh Token은 일반 RDB가 아닌 TTL 기반의 인메모리 저장소인 Redis에서 관리하는 것이 보안성과 성능, 유지관리 효율성 측면에서 훨씬 더 적합한 선택임을 확인할 수 있었습니다."

마무리

다음 포스트에서는 Refresh Token의 필요성과 역할을 짚고, 전체 인증 구조 내에서 어떻게 설계되고 적용되는지 정리하겠습니다.

0개의 댓글