현재 로직
1. User가 회원가입 진행 시 coolSms를 통해 인증코드를 발급받는다.
2. redis에 sms:{email} 형식으로 저장되면 data에 발급받은 coolSms로 전송된 인증 코드를 저장한다.
3. User가 전송받은 인증코드를 [확인] 버튼을 누를 경우 redis 내의 코드와 비교한다.
→ 현재는 보안을 생각해서 이 단계에서 인증 코드를 삭제하지 않고, 회원가입 버튼을 누를 경우 DTO에 인증 코드를 다시 전송하여 회원가입 로직에서 Redis의 인증 코드와 일치하는지 다시 확인한다.
→ 인증 코드 검증과 회원가입 버튼을 누르기까지 큰 시간의 차이가 없어서 괜찮을 것 같지만 뭔가 찝찝한게 문제.......
오.!>!>1>!>!!>?!!?~ 귀찮 ㅠ
Redis 전화번호 인증 성공 시
1. module-common → [SmsServiceImpl]
- 전화번호 인증 성공 시 redis에 verified_phone:{phone} 형식으로 저장, 타임아웃은 10분으로 지정
@Override
public boolean verifySms(SmsVerifyRequest smsVerifyRequest){
String phone = smsVerifyRequest.getPhoneNum();
Sms sms = findSmsByPhone(phone);
if(sms.getCode().equals(smsVerifyRequest.getCertificationCode())){
deleteByPhone(phone);
verifyPhone(phone);
return true;
}
return false;
}
public void verifyPhone(String phone) {
// Redis에 "verified_phone:{phone}" 형식으로 저장
String redisKey = "verified_phone:" + phone;
// 로그아웃 상태를 기록 (true로 설정)
redisTemplate.opsForValue().set(redisKey, "verify");
// 1시간 동안 유효 (예: 로그아웃 상태를 1시간 동안 유지)
redisTemplate.expire(redisKey, Duration.ofMinutes(10));
}
2. module-common → [AuthServiceImpl]
- 회원가입 시 redis에 verified_phone:{phone} 있는지 확인하는 로직 추가
- 확인 완료 시 redis 내 해당 인증정보 삭제
/** [일반] 이메일 회원가입 API
* 이메일, 전화번호, 닉네임 중복 체크
* 중복 없을 시 member 저장
* 프로필 저장 Version
* */
@Transactional
public void signup(SignupRequest request) {
// CHECK EMAIL, PHONE, NICKNAME DUPLICATE
if(memberService.existByEmail(request.getEmail())){
throw new DataIntegrityViolationException("중복되는 이메일입니다.");
}
if(memberService.existByPhone(request.getPhone())){
throw new DataIntegrityViolationException("중복되는 전화번호입니다.");
}
if(memberService.existByNickname(request.getNickname())){
throw new DataIntegrityViolationException("중복되는 닉네임입니다.");
}
// 인증되지않은 전화번호
if(!isTokenPhone(request.getPhone())){
throw new DataIntegrityViolationException("잘못된 요청입니다.");
}
// 회원가입 후 Redis에 저장된 전화번호 인증 정보를 삭제
deletePhoneNumberVerification(request.getPhone());
Member member = Member.builder()
.email(request.getEmail())
.nickname(request.getNickname())
.phone(request.getPhone())
.gender(request.getGender())
.password(passwordEncoder.encode(request.getPassword()))
.birthday(request.getBirthday())
.role(Role.ROLE_USER)
.provider(Provider.NORMAL)
.build();
// SAVE MEMBER ENTITY
memberService.saveMember(member);
}
/**
* redis에 인증된 전화번호인지 체크
* */
public boolean isTokenPhone(String phone) {
// Redis에 해당 번호가 존재하는지 확인
return Boolean.TRUE.equals(redisTemplate.hasKey(getRedisKeyForToken(phone)));
}
private String getRedisKeyForToken(String token) {
return "verified_phone:" + token;
}
테스트
- 전화번호 인증없이 바로 회원가입 API에 데이터를 넣은 경우 → 실패
인증없이 추가한 경우 예외처리 됨 (아직 예외처리 코드를 지정하지않아서 이후에 변경 예정)
- 인증번호 발급
- 인증 완료
- Redis 내에 인증된 전화번호로 등록 성공
- 회원가입 → 실패
Redis 내에서도 해당 전화번호 인증 정보가 정상적으로 삭제되었다
'개발' 카테고리의 다른 글
[Spring Cloud Gateway] Admin 로그인 API가 따로 필요한가 ? ? (0) | 2024.09.10 |
---|---|
[Spring Cloud Gateway] module-admin (0) | 2024.09.09 |
[Spring Cloud Gateway] 로그아웃 확인 (0) | 2024.09.05 |
[Spring Cloud Gateway] 회원가입, 로그인 라우팅 확인 (2) | 2024.09.04 |
[Spring Cloud Gateway] Springboot Eureka 설정 (0) | 2024.09.03 |