✅ 작업 목표
- JWT 기반 로그인/회원가입/재발급/로그아웃/탈퇴 기능 완성
- 사용자 상태 관리 및 예외 코드 도입
- Redis 기반 RefreshToken 저장 및 삭제 처리
1️⃣ 회원가입 기능
- 요청 경로: POST /api/v1/users/signup
- 비밀번호는 bcrypt로 암호화
- 닉네임 중복 체크
- 예외 코드 적용 (EMAIL_DUPLICATION, NICKNAME_DUPLICATION)
userRepository.checkNicknameDuplicate(dto.getNickname());
userRepository.checkEmailDuplicate(dto.getEmail());
2️⃣ 로그인 기능
- 요청 경로: POST /api/v1/users/signin
- 이메일/비밀번호 검증
- 로그인 성공 시 accessToken, refreshToken 발급
- refreshToken은 Redis에 refresh_token:{userId} 키로 저장
redisTemplate.opsForValue().set(
"refresh_token:" + user.getId(),
token.getRefreshToken(),
jwtTokenProvider.getRefreshTokenDuration()
);
3️⃣ JWT 재발급 (reissue)
- 요청 경로: POST /api/v1/users/reissue
- 전달받은 RefreshToken 기반으로 새 토큰 발급
- Redis에 저장된 토큰과 일치하지 않으면 TOKEN_NOT_MATCHED 예외 발생
if (!savedToken.equals(dto.getRefreshToken())) {
throw new UserException(UserExceptionCode.TOKEN_NOT_MATCHED);
}
4️⃣ 로그아웃
- 요청 경로: POST /api/v1/auth/logout
- @AuthenticationPrincipal로 userId 추출
- Redis에서 해당 유저의 RefreshToken 삭제
redisTemplate.delete("refresh_token:" + userId);
5️⃣ 회원 탈퇴 (소프트 삭제)
- 요청 경로: DELETE /api/v1/users/withdraw
- AccessToken으로 인증된 사용자만 요청 가능
- 요청 시 비밀번호 검증 포함 (validatePassword)
- 상태를 UserStatus.DELETED로 변경
user.validatePassword(rawPassword, passwordEncoder);
user.softDelete(); // 상태: DELETED
🛡️ 공통 예외 처리
- 각 도메인별 커스텀 예외 코드(enum) 도입
- UserExceptionCode로 상세한 예외 분기 처리
- GlobalExceptionHandler를 통한 일관된 에러 응답 제공
USER_NOT_FOUND,
INVALID_PASSWORD,
EMAIL_DUPLICATION,
TOKEN_NOT_MATCHED,
USER_DELETED
🔐 인증 흐름 정리
- 로그인 → 토큰 발급 → Redis 저장
- AccessToken → API 요청 시 헤더에 포함
- RefreshToken → 재발급 요청 시 body로 전달
- 로그아웃 → Redis 키 삭제
- 탈퇴 → 비밀번호 확인 + status 변경
'TIL' 카테고리의 다른 글
| [240424] 회원 기능 테스트 코드 (2) | 2025.04.24 |
|---|---|
| [250423 TIL] 배달어플 소셜로그인 (1) | 2025.04.23 |
| [250416] 스프링 심화 과제 회고 (2) | 2025.04.16 |
| [250414 TIL] 뉴스피드 KPT (2) | 2025.04.14 |
| [250411 TIL] 영속성 컨텍스트 심화 (1) | 2025.04.11 |