MMeshOps
Redis 실전: 서비스 장애를 막는 안전한 캐싱과 상태 관리
10예상 10중급

보안과 인증: 세션 관리 및 이메일 인증 코드 저장

수명이 명확한 데이터인 사용자 세션과 이메일 인증 코드를 Redis에 저장하고 관리하는 실전 패턴을 알아봅니다.

우리가 매일 사용하는 로그인 기능이나 이메일 인증은 사실 서버 입장에서는 아주 까다로운 작업입니다. 수많은 사용자가 동시에 로그인하고 인증을 요청할 때, 매번 메인 데이터베이스에 기록한다면 서비스 전체가 느려질 수 있습니다.

이번 에포소드에서는 수명이 명확한 인증 관련 데이터를 Redis에서 어떻게 관리하는지, 그리고 이 방법이 왜 메인 데이터베이스를 보호하는 핵심 방패가 되는지 알아봅니다.

세션(Session) 저장소로서의 Redis

웹 서비스에서 로그인을 유지하려면 사용자의 인증 상태(세션)를 서버 어딘가에 저장해야 합니다. 과거에는 이 데이터를 웹 서버 메모리에 직접 저장했지만, 서버가 여러 대가 되면 로그인이 풀려버리는 치명적인 문제가 발생합니다.

이 문제를 해결하기 위해 Redis를 공통 세션 저장소로 사용하는 패턴이 등장했습니다. 어떤 서버에 접속하든 모든 서버가 중앙의 Redis에서 세션 정보를 확인하므로 일관된 로그인 상태를 유지할 수 있습니다.

서버 간 세션 공유 아키텍처

사용자

로그인 요청

웹 서버 A

웹 서버 A

세션 생성 및 저장

Redis

사용자

다음 페이지 요청

웹 서버 B

웹 서버 B

세션 확인

Redis

왜 PostgreSQL 대신 Redis인가?

세션 데이터는 보통 하루나 일주일 정도만 유지되면 충분합니다. 굳이 영구 저장소인 메인 데이터베이스에 로그인 상태를 기록할 필요가 없죠. 또한, 세션 확인은 모든 페이지 이동마다 발생하기 때문에 매우 빠른 읽기 속도가 필요합니다. Redis는 메모리 기반이므로 이 조건에 완벽하게 부합합니다.

세션 저장소 비교: DB vs Redis

비교 항목PostgreSQL (메인 DB)Redis
읽기 속도디스크 접근으로 상대적 느림메모리 접근으로 매우 빠름
디스크 부하모든 요청마다 디스크 I/O 발생디스크 부하 없음
데이터 자동 삭제별도의 삭제 배치 작업 필요TTL 기능으로 자동 소멸

이메일 인증 코드와 단기 데이터

회원가입 시 이메일이나 문자로 전송되는 6자리 인증 코드를 떠올려보세요. 이 데이터는 다음과 같은 명확한 특징이 있습니다.

  1. 매우 짧은 수명: 보통 3분~5분 후에는 무용지물이 됩니다.
  2. 단순한 구조: 이메일 주소와 숫자 6자리만 매칭되면 됩니다.
  3. 영구 보존 불필요: 인증이 완료되거나 시간이 지나면 영원히 사라져도 괜찮습니다.

이런 데이터는 메인 데이터베이스에 넣으면 쓰레기 데이터만 쌓이게 됩니다. Redis를 활용하면 이런 단기 데이터를 아주 우아하게 처리할 수 있습니다.

Redis를 활용한 인증 코드 관리 패턴

이메일 주소를 키(Key)로, 인증 코드를 값(Value)으로 저장하면서 앞서 배운 TTL(만료 시간)을 3분으로 설정합니다. 이렇게 하면 코드를 직접 삭제할 필요 없이 시간이 지나면 알아서 사라집니다.

인증 코드 저장 및 검증 예시

// 1. 인증 코드 발급 (3분 TTL)
async function sendAuthCode(email) {
  const code = generate6DigitCode();
  // 키: auth:[email protected], 값: 123456, 만료: 180초
  await redis.set(`auth:${email}`, code, { EX: 180 });
  await sendEmail(email, code);
}

// 2. 인증 코드 검증
async function verifyAuthCode(email, userInput) {
  const savedCode = await redis.get(`auth:${email}`);
  
  if (!savedCode) return "만료되거나 없는 코드입니다.";
  if (savedCode !== userInput) return "코드가 일치하지 않습니다.";
  
  // 인증 성공 시 보안을 위해 코드 즉시 삭제
  await redis.del(`auth:${email}`);
  return "인증 완료";
}

보안을 위한 인증 횟수 제한

여기서 한 걸음 더 나아가 볼까요? 해커가 무작위 숫자를 계속 입력해서 인증을 뚫으려 할 수 있습니다. 이를 방지하기 위해 '해당 이메일의 실패 횟수'도 Redis에 저장할 수 있습니다.

이처럼 Redis는 단순히 빠른 캐시를 넘어, 상태(State)를 추적하고 제어하는 강력한 보안 도구로 활약합니다.

인증 데이터 저장 시 흔한 실수

오해 또는 실수

인증 코드를 메인 DB에 저장하고 주기적으로 삭제 안 함

바로잡기

Redis의 TTL을 활용해 자동 만료되도록 설계

오해 또는 실수

인증 완료 후에도 코드를 삭제하지 않음

바로잡기

인증이 성공하면 즉시 코드를 무효화(삭제)하여 재사용 방지

개념 퀴즈

퀴즈 답을 맞춰야 학습 완료가 됩니다.

이메일 인증 코드와 같이 수명이 짧은 데이터를 Redis에 저장할 때 가장 유용한 기능은 무엇인가요?

3줄 요약

  1. 1서버가 여러 대일 경우, 로그인이 풀리는 문제를 막기 위해 Redis를 중앙 세션 저장소로 사용합니다.
  2. 2이메일 인증 코드처럼 수명이 짧고 영구 보존이 필요 없는 데이터는 메인 DB 대신 Redis에 저장해야 합니다.
  3. 3Redis의 TTL 기능을 결합하면 단기 인증 데이터를 안전하고 효율적으로 만료시킬 수 있습니다.