Skip to content

Commit

Permalink
feat: 문자 인증 시 TTL 설정
Browse files Browse the repository at this point in the history
  • Loading branch information
dgjinsu committed Nov 21, 2024
1 parent d4ed330 commit 8e3b08a
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public class JoinCompanyRequest {
@Schema(description = "휴대폰 번호", example = "01012345678")
@NotBlank
private String phone;
@Schema(description = "본인 확인 인증 번호", example = "123456")
@NotBlank
private String authCode;
@Schema(description = "회원 타입 [ROLE_WORKER or ROLE_COMPANY]", example = "ROLE_COMPANY")
@NotNull
private Role role; // 회원 타입
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ public class JoinWorkerRequest {
// 공통 정보
@Schema(description = "로그인 아이디", example = "abcdefg1")
@NotBlank
private String loginId; // 인증 코드
private String loginId;
@Schema(description = "로그인 패스워드", example = "abcdefg1")
@NotBlank
private String password; // 인증 코드
private String password;
@Schema(description = "휴대폰 번호", example = "01012345678")
@NotBlank
private String phone; // 휴대폰 번호
private String phone;
@Schema(description = "본인 확인 인증 번호", example = "123456")
@NotBlank
private String authCode;
@Schema(description = "이메일", example = "[email protected]")
@Email
private String email; // 이메일
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/jikgong/domain/member/service/JoinService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import jikgong.domain.common.Address;
import jikgong.domain.location.entity.Location;
Expand All @@ -24,6 +25,7 @@
import jikgong.global.utils.RandomCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -39,11 +41,16 @@ public class JoinService {
private final WorkExperienceRepository workExperienceRepository;
private final PasswordEncoder encoder;
private final SmsService smsService;
private final RedisTemplate<String, String> redisTemplate;

private static final String REDIS_PREFIX_SIGNUP_VERIFICATION = "signup_verification:";

/**
* 노동자 회원가입 위치 정보 저장
*/
public Long joinWorkerMember(JoinWorkerRequest request) {
// 인증 코드 유효 시간 검사
validationAuthCode(request);
// loginId 중복 체크
validationLoginId(request.getLoginId());
// 휴대폰 중복 체크
Expand Down Expand Up @@ -98,6 +105,15 @@ public Long joinWorkerMember(JoinWorkerRequest request) {
return savedMember.getId();
}

// 인증 코드 유효 시간 검사
private void validationAuthCode(JoinWorkerRequest request) {
String redisKey = REDIS_PREFIX_SIGNUP_VERIFICATION + request.getPhone();
String savedAuthCode = redisTemplate.opsForValue().get(redisKey);
if (savedAuthCode == null || !savedAuthCode.equals(request.getAuthCode())) {
throw new JikgongException(ErrorCode.MEMBER_INVALID_AUTH_CODE); // 인증 코드 불일치
}
}

/**
* 기업 회원가입
*/
Expand Down Expand Up @@ -168,6 +184,10 @@ public VerificationSmsResponse verificationSms(VerificationSmsRequest request) {
throw new JikgongException(ErrorCode.SMS_SEND_FAIL);
}

// Redis에 인증 코드와 회원 정보를 저장 (TTL 5분)
String redisKey = REDIS_PREFIX_SIGNUP_VERIFICATION + request.getPhone();
redisTemplate.opsForValue().set(redisKey, authCode, 5, TimeUnit.MINUTES);

return new VerificationSmsResponse(authCode);
}

Expand Down
25 changes: 17 additions & 8 deletions src/main/java/jikgong/domain/member/service/MemberInfoService.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class MemberInfoService {
private final SmsService smsService;
private final StayExpirationService stayExpirationService;

private static final String REDIS_PREFIX_PASSWORD_RESET = "password_reset:";

/**
* 노동자: 회원 정보 조회
*/
Expand Down Expand Up @@ -210,20 +212,16 @@ public void verificationBeforeFindLoginId(LoginIdFindRequest request) {
}

// Redis에 인증 코드와 회원 정보를 저장 (TTL 5분)
redisTemplate.opsForValue().set(member.getPhone(), authCode, 5, TimeUnit.MINUTES);
String redisKey = REDIS_PREFIX_PASSWORD_RESET + member.getPhone();
redisTemplate.opsForValue().set(redisKey, authCode, 5, TimeUnit.MINUTES);
}

/**
* 문자로 인증된 코드로 아이디 찾기
*/
public LoginIdFindResponse findLoginId(AuthCodeForFindRequest request) {
// Redis에 저장된 인증 코드 가져오기
String savedAuthCode = redisTemplate.opsForValue().get(request.getPhone());

// 인증 코드가 일치하는지 체크
if (savedAuthCode == null || !savedAuthCode.equals(request.getAuthCode())) {
throw new JikgongException(ErrorCode.MEMBER_INVALID_AUTH_CODE); // 인증 코드 불일치
}
// // 인증 코드가 일치하는지 체크
validationAuthCode(request);

Member member = memberRepository.findByPhone(request.getPhone())
.orElseThrow(() -> new JikgongException(ErrorCode.MEMBER_NOT_FOUND));
Expand All @@ -232,6 +230,17 @@ public LoginIdFindResponse findLoginId(AuthCodeForFindRequest request) {
return LoginIdFindResponse.from(member);
}

// 인증 코드가 일치하는지 체크
private void validationAuthCode(AuthCodeForFindRequest request) {
// Redis에 저장된 인증 코드 가져오기
String redisKey = REDIS_PREFIX_PASSWORD_RESET + request.getPhone();
String savedAuthCode = redisTemplate.opsForValue().get(redisKey);

if (savedAuthCode == null || !savedAuthCode.equals(request.getAuthCode())) {
throw new JikgongException(ErrorCode.MEMBER_INVALID_AUTH_CODE); // 인증 코드 불일치
}
}

/**
* 체류 만료일 조회 api 호출
* 체류 만료일 정보 업데이트
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/jikgong/global/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public enum ErrorCode {
MEMBER_UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "MEMBER-009", "인증이 필요합니다."),
MEMBER_FORBIDDEN(HttpStatus.FORBIDDEN, "MEMBER-010", "권한이 필요합니다."),
MEMBER_CONSENTS_NEED_TO_AGREE(HttpStatus.FORBIDDEN, "MEMBER-011", "회원가입을 위해선 각종 내용에 동의해야합니다."),
MEMBER_INVALID_AUTH_CODE(HttpStatus.BAD_REQUEST, "MEMBER-012", "아이디를 찾기 위해 입력한 인증 코드가 올바르지 않습니다."),
MEMBER_INVALID_AUTH_CODE(HttpStatus.BAD_REQUEST, "MEMBER-012", "인증 코드가 올바르지 않습니다."),
MEMBER_NOT_STAY_WITH_IN_THE_COUNTRY(HttpStatus.BAD_REQUEST, "MEMBER-013", "현재 체류 중인 외국인이 아닙니다."),

/**
Expand Down

0 comments on commit 8e3b08a

Please sign in to comment.