Spring Boot에서 비밀번호 변경 기능을 구현하려고 한다. 구현 전에 먼저 알아둘 것을 정리해본다.
비밀번호 변경 과정
1. 회원가입이 되어 있는 상태여야 한다.
2. 로그인 상태여야 한다.
3. DB에는 암호화된 password(pw)가 저장되어 있다.
4. 사용자에게 기존 pw와 새로운 pw를 입력 받는다.
5. 기존 pw가 현재 사용자의 pw와 일치한다면 해당 회원의 pw를 새로운 pw로 변경한다.
6. 일치하지 않는다면 오류를 발생시킨다.
UpdatePasswordReq
@Getter
public class UpdatePasswordReq {
@NotBlank
private String currentPassword;
@NotBlank
@Pattern(regexp = "(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[!@#$%^&*]).{8,16}",
message = "비밀번호는 8~16자 영문 대 소문자, 숫자, 특수문자를 사용하세요.")
private String newPassword;
- 비밀번호 변경에 필요한 request 객체
Member
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Entity
@Getter
public class Member extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String email;
private String password;
private String image;
public void updatePassword(String newPassword) {
this.password = newPassword;
}
}
- Member 엔티티는 위와 같다. updatePassword() 메서드가 구현되어 있다.
MemberController
@RestController
@RequiredArgsConstructor
@RequestMapping("/members")
public class MemberController {
@Operation(summary = "비밀번호 변경", description = "로그인한 회원 비밀번호 변경")
@PatchMapping("/me/password")
public void updatePassword(@Validated @RequestBody UpdatePasswordReq updatePasswordReq) {
String email = MemberUtils.getAuthMember().getUsername(); //현재 로그인한 회원의 email
memberService.updatePassword(email, updatePasswordReq.getCurrentPassword(), updatePasswordReq.getNewPassword());
}
}
- 현재 로그인 한 회원이 기존 pw와 새 pw를 받아 memberService로 넘긴다.
MemberService
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
private final PasswordEncoder passwordEncoder;
@Transactional
public void updatePassword(String email, String currentPassword, String newPassword) {
Member member = validatePassword(email, currentPassword);
member.updatePassword(passwordEncoder.encode((newPassword)));
}
public Member validatePassword(String email, String password) {
Member member = memberRepository.findByEmail(email)
.orElseThrow(NonExistentMemberException::new);
if (!passwordEncoder.matches(password, member.getPassword())) {
throw new InvalidPasswordException();
}
return member;
}
}
- validatePassword()는 회원의 email로 일치하는 회원을 먼저 조회한다.
- 회원의 password와 사용자로부터 입력받은 기존 pw가 일치하는지 PasswordEncoder의 matches()를 통해 확인한다.
- 일치하면 Member 엔티티를 반환하고 해당 Member의 password를 encoding하여 변경한다.
- 일치하지 않으면 아래의 Exception을 throw 한다.
InvalidPasswordException
public class InvalidPasswordException extends RuntimeException {
public InvalidPasswordException() {
super(ExceptionCodeMessage.INVALID_PASSWORD_EXCEPTION.message());
}
public InvalidPasswordException(String message) {
super(message);
}
public InvalidPasswordException(String message, Throwable cause) {
super(message, cause);
}
public InvalidPasswordException(Throwable cause) {
super(cause);
}
public InvalidPasswordException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
'💻dev > 🌱Java+Spring' 카테고리의 다른 글
Springboot 프로젝트에서 에러 메시지를 클래스로 관리하기 (0) | 2024.02.21 |
---|---|
Spring | @Annotation 어노테이션은 어떻게 동작할까? (0) | 2023.10.29 |
Spring Security | 회원정보 수정 기능 구현 (0) | 2023.08.11 |
Spring Security | PasswordEncoder를 사용하여 회원가입시 비밀번호 암호화 하기 (0) | 2023.08.11 |
Spring | @ConfigurationProperties와 @ConfigurationPropertiesScan (0) | 2023.08.11 |