Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] 비밀번호 재설정 기능을 구현한다. #843

Merged
merged 39 commits into from
Nov 13, 2024

Conversation

tkdgur0906
Copy link
Contributor

❗ Issue

✨ 구현한 기능

  • 이메일로 인증번호 전송
  • 인증번호 검증
  • 재설정된 비밀번호로 업데이트

📢 논의하고 싶은 내용

🎸 기타

LocalDateTime 테스트를 위해 Clock을 빈으로 등록했습니다.
yml파일 mail관련 설정 업데이트 예저입니다.

Copy link
Contributor

@shin-jisong shin-jisong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다~

@@ -30,12 +38,16 @@ public class AuthService {

private static final Logger log = LoggerFactory.getLogger(AuthService.class);
private static final int GUEST_USER_LIMIT = 1;
private static final int PASSWORD_RESET_CODE_EXPIRED_MINUTES = 3;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5분 혹은 10분이 적당하지 않을까요?!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5분으로 변경했습니다!

}

userRepository.updatePasswordByEmail(
new Email(request.email()), new Password(request.newPassword()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 패스워드 리셋 코드 저장한 걸 삭제하는 건 어떨까요?!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반영했습니다!

Comment on lines 36 to 37
void updatePasswordByEmail(@Param("email") Email email, @Param("newPassword") Password newPassword);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로그인 타입도 지정해 줘야 될 것 같아요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 완전 예리한 리뷰네요, 수정했습니다!

@Autowired
private PasswordResetCodeRepository passwordResetCodeRepository;

@DisplayName("특정 시간보다 나중에 생성된 비밀번호 초기화 코드 존재 시 참 반환")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

컨벤션이랑 살짝 다른 것 같아서 확인해 주세요!

Copy link
Contributor

@tsulocalize tsulocalize left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

간단한 리뷰 남겨드렸습니다~

.hasMessage(ExceptionCode.AUTHENTICATION_PASSWORD_CODE_NOT_FOUND.getMessage());
}

@DisplayName("비밀번호 재설정 선공")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

선공 -> 성공


class MailSenderTest {

@DisplayName("이메일 전송 시 send 메소드 호출")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 성공

Copy link
Contributor

@JINU-CHANG JINU-CHANG left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고많으셨어요~! 코멘트 몇가지 남겼습니다 🚀

Comment on lines +15 to +18
@Getter
@NoArgsConstructor(access = PROTECTED)
@Entity
public class PasswordResetCode extends BaseEntity {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일회성 데이터 같아서 DB에 저장할 필요는 없다고 생각되는데 혹시 다른 방식 고민해보신게 있나요??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일단 어딘가에 저장되어야하긴 해서 DB에 저장했습니다.
유효시간도 있다보니 레디스에 저장하는게 최선 같은데, 우선은 간단하게 DB에 저장하는 방식으로 구현했습니다!

Comment on lines 3 to 4
public record ConfirmPasswordResetCodeRequest(String email, String code) {
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요기는 Valid 필요없나요??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dto에서 email 검증하도록 변경했습니다!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code도 @notblank 필요하지 않나요 👀

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code랑 newPassword도 추가해줬습니다!

@@ -109,6 +121,31 @@ public void logout(String accessToken, String refreshToken, User user) {
validateTokenOwnership(user, accessAuthUser, refreshAuthUser);
}

public void sendPasswordResetEmail(ForgotPasswordRequest request) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@transactional 빠진 것 같아요 👀

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드가 메일 보내는 api랑 같이 묶여있어서 붙이지 않았습니다!
save만 단건으로 트랜잭션 처리되도 괜찮을 것 같아요

Comment on lines 48 to 50
private final MailSender mailSender;
private final PasswordResetCodeRepository passwordResetCodeRepository;
private final Clock clock;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

비밀번호 찾기에 대한 코드량이 상당한 것 같은데 새로운 서비스로 분리해보는 건 어떨까요? 해당 클래스들이 의존성을 가질 수 있겠네요!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

비밀번호 찾기에 대한 서비스를 만들어서 분리했습니다!


@Value("${spring.mail.properties.mail.smtp.debug}")
private boolean debug;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

공백 👀

return ResponseEntity.noContent().build();
}

@PostMapping("/v1/password-reset/new-password")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@PostMapping("/v1/password-reset/new-password")
@PostMapping("/v1/password-reset")

마지막은 new-password 단어를 빼도 의미전달이 될 것 같은데 어떠신가용

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반영했습니다!

@tkdgur0906 tkdgur0906 changed the base branch from dev to dev-be November 11, 2024 01:41
Copy link
Contributor

@tsulocalize tsulocalize left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코멘트 추가해두었습니다~

Comment on lines 36 to 44
@Transactional(readOnly = true)
public void confirmPasswordResetCode(ConfirmPasswordResetCodeRequest request) {
LocalDateTime timeLimit = LocalDateTime.now(clock).minusMinutes(PASSWORD_RESET_CODE_EXPIRED_MINUTES);
boolean isValid = passwordResetCodeRepository.existsByEmailAndCodeAndCreatedAtAfter(
new Email(request.email()), request.code(), timeLimit);
if (!isValid) {
throw new BangggoodException(ExceptionCode.AUTHENTICATION_PASSWORD_CODE_NOT_FOUND);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드를 확인한 뒤에 확인했다라는 정보를 어디에 기록해두고 있나요?
현재 상태로는 코드 확인 절차 없이도 비밀번호 리셋이 가능한 것 같아 보이네요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드가 확인되었는지 확인하는 변수를 추가하는 방식으로 변경했습니다!

Comment on lines 50 to 52
if (!passwordResetCodeRepository.existsByEmailAndCode(email, code)) {
throw new BangggoodException(ExceptionCode.AUTHENTICATION_PASSWORD_CODE_NOT_FOUND);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

예시) 한 유저는 리셋 코드를 10개를 미리 발급해두었다. 이후 리셋 코드를 필요할 때마다 기존 발급한 코드를 사용했다.

위 동작을 의도한 건 아니지 않나요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리셋 코드 생성 시 기존 코드 삭제하도록 수정했습니다!

Copy link
Contributor

@tsulocalize tsulocalize left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다!

Copy link
Contributor

@JINU-CHANG JINU-CHANG left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

카피 수고많으셨어요 ~~ 👍

Copy link
Contributor

@shin-jisong shin-jisong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다!

@shin-jisong shin-jisong merged commit 79084ee into dev-be Nov 13, 2024
2 checks passed
@shin-jisong shin-jisong deleted the feat/807-find-password branch November 13, 2024 07:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants