[기능 목표]

비밀번호를 잊은 사용자가 본인 인증 후 비밀번호를 안전하게 변경할 수 있도록 구현

기존에는 비밀번호 변경 -> 이메일 검증(/valid) -> 새로운 비밀번호 입력(/updatepassword)

이때 새로운 비밀번호 입력 요청에서 진짜 우리 프론트에서 보낸 요청인지 검증하는 부분이 빠졌음

공격자가 postman 같은 걸로 /updatepassword 이 요청에 비밀번호 넣어서 보내면 수정될 가능성 있음

 

기존에는 비밀번호 변경

-> 이메일 검증(/valid-password) + 임시토큰 발행

-> Redis에 저장 + 프론트로 전송

-> 새로운 비밀번호 + 토큰(/updatepassword)

 

주요 흐름 및 로직 구성

1. 이메일 인증 기능을 "가입용"과 "비밀번호 변경용"으로 분리

2. 비밀번호 변경용 이메일 인증 후 → 임시 토큰 발급

목적 설명
임시 토큰 발급 인증된 사용자가 다음 단계(비밀번호 변경 요청)를 수행할 수 있도록 임시 토큰을 Redis에 저장
key 포맷 password_reset_token:{email}
value UUID (예: 4a911ded-ac5e-4820-a25b-c59a60b4dec0)
TTL 짧은 시간만 유효 (3분)

3. 프론트에서는

 

  • 사용자 이메일로 인증 요청
  • 인증 코드 입력 → 서버에서 검증 성공 시 임시 토큰 발급
  • 클라이언트가 token과 newPassword를 포함해 비밀번호 변경 요청 전송

 

POST /api/v2/users/password-reset

{
  "email": "subin4420@gmail.com",
  "password": "newPassword123!",
  "token": "4a911ded-ac5e-4820-a25b-c59a60b4dec0"
}

4. 서버에서는?

  • password_reset_token:{email} 키로 Redis에서 토큰을 꺼냄
  • 사용자가 준 token과 일치하면 통과
  • 비밀번호 변경 후 토큰 삭제 (deleteValue)
  • 위조된 요청 방지 및 1회성 처리 보장

마무리

비밀번호 변경 기능을 구현하면서 팀원과 함께 다음 두 가지 방식을 논의했다.

  1. 이메일 인증 후 "임시 비밀번호"를 이메일로 발급하고,
    사용자가 로그인한 뒤 비밀번호를 다시 변경하는 방식
  2. 이메일 인증 후 서버에서 임시 토큰을 발급하고,
    사용자가 새로운 비밀번호를 직접 설정하는 방식 (→ 현재 적용 방식)

첫 번째 방식은 실제로 많이 사용되는 사례이긴 하지만,

  • 임시 비밀번호를 복사해 로그인해야 하고
  • 로그인 후 다시 비밀번호 변경 과정을 거쳐야 하며
  • 사용자가 임시 비밀번호를 노출할 위험도 있음

→ 보안성과 사용자 경험 측면에서 단점이 있다고 생각했다.

따라서 우리는 두 번째 방식을 선택했다.
즉, 이메일 인증 후 임시 토큰을 Redis에 저장하고,
사용자는 이 토큰을 가지고 바로 새로운 비밀번호를 설정할 수 있도록 구성했다.

이 방식은:

  • 불필요한 로그인 절차 없이 곧바로 비밀번호를 바꿀 수 있고,
  • 임시 토큰은 짧은 시간만 유효하므로 보안성도 확보할 수 있다.

결과적으로 사용자 경험과 보안 측면에서 더 나은 선택인 것 같다.

 

Redis를 통해 잠깐 쓸 데이터 저장하고(키를 통해 사용자 별로) 사용이 끝나면 지워버리는 방식을 사용해 봤는데, 개발하는 과정에서 많이 사용되는 방식 같다.

+ Recent posts