비밀번호 재설정 구현2
String MemberController .patchRecoverPassword (EmailAuthEntity emailAuth, UserEntity user)
Enum<? extends IResult> MemberService .recoverPassword (EmailAuthEntity emailAuth, UserEntity user)
서비스 로직
1. 전달 받은 EmailAuthEntity 타입의 emailAuth가 가진 email, code, salt를 통해 테이블에서 새로운 EmailAuthEntity 객체를 SELECT 해온다.
2. <1>에서 SELECT한 객체가 null 이거나 isExpried() 호출 결과가 false 인 경우 FAILURE 반환. 끝.
3. <1>에서 SELECT한 객체가 가진 email 값으로 새로운 UserEntity 타입의 객체를 SELECT 해온다.
4. <3> 에서 SELECT한 UserEntity 타입의 객체에 대해 PRIMARY KEY 필드를 기준으로 나머지 열 전체에 대해 UPDATE 한다.
5. <4> 에서 수정한 UserEntity 타입의 객체에 대해 PRIMARY KEY 필드를 기준으로 나머지 열 전체에 대해 UPDATE 한다.
6. <5> 의 결과가 0이면 FAILURE, 아니면 SUCCESS를 반환. 끝.
5번은 없을거니 만들어주어야 함
스따뜨!
MemberMapper.xml
<update id="updateUser"
parameterType="dev.xowoony.studymemberbbs.entities.member.UserEntity">
UPDATE `study_member`.`users`
SET `password` = #{password},
`nickname` = #{nickname},
`name` = #{name},
`contact`= #{contact},
`address_postal` = #{addressPostal},
`address_secondary` = #{addressSecondary},
`registered_on` = #{registeredOn}
WHERE BINARY `email` = #{email}
LIMIT 1
</update>
IMemberMapper.java
int updateUser(UserEntity user);
// updateUser 라고 만들어놓으면 password 등등 쓰일일이 많이 있기 때문에 여러모로 편하다.
// int 타입으로 만들어 주는 이유는 영향을 받은 갯수를 반환할 것이기 때문이다.
MemberController.java
@RequestMapping(value = "recoverPassword",
method = RequestMethod.PATCH,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String patchRecoverPassword(EmailAuthEntity emailAuth, UserEntity user) {
Enum<?> result = this.memberService.recoverPassword(emailAuth, user);
JSONObject responseObject = new JSONObject();
responseObject.put("result", result.name().toLowerCase());
return responseObject.toString();
}
MemberService.java
@Transactional
public Enum<? extends IResult> recoverPassword(EmailAuthEntity emailAuth, UserEntity user) {
//
EmailAuthEntity existingEmailAuth = this.memberMapper.selectEmailAuthByEmailCodeSalt(
emailAuth.getEmail(),
emailAuth.getCode(),
emailAuth.getSalt());
if (existingEmailAuth == null || !existingEmailAuth.isExpired()) {
return CommonResult.FAILURE;
}
UserEntity existingUser = this.memberMapper.selectUserByEmail(existingEmailAuth.getEmail());
existingUser.setPassword(CryptoUtils.hashSha512(user.getPassword())); // 비번 해싱후 수정
if (this.memberMapper.updateUser(existingUser) == 0) { // 데이터중 비번만 바꾸고 다시 집어넣음
return CommonResult.FAILURE;
}
return CommonResult.SUCCESS;
}
recoverPassword.js
// 비밀번호 재설정 폼 등장
form['recover'].addEventListener('click', () => {
Warning.hide();
if (form['password'].value === '') {
Warning.show('새로운 비밀번호를 입력해 주세요.');
form['password'].focus();
return;
}
if (form['password'].value !== form['passwordCheck'].value) {
Warning.show('비밀번호가 서로 일치하지 않습니다.');
form['passwordCheck'].focus();
form['passwordCheck'].select();
return;
}
Cover.show('비밀번호를 재설정하고 있습니다.\n잠시만 기다려 주세요.');
const xhr = new XMLHttpRequest();
const formData = new FormData();
formData.append('email', form['email'].value);
formData.append('code', form['code'].value);
formData.append('salt', form['salt'].value);
formData.append('password', form['password'].value);
xhr.open('PATCH', './recoverPassword');
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
Cover.hide();
if (xhr.status >= 200 && xhr.status < 300) {
const responseObject = JSON.parse(xhr.responseText);
switch (responseObject['result']) {
case'success':
alert('비밀번호를 성공적으로 재설정하였습니다.\n\n확인을 누르면 로그인 페이지로 이동합니다.');
window.location.href = 'login';
break;
default:
Warning.show('비밀번호를 재설정하지 못하였습니다. 세션이 만료되었을 수도 있습니다. 잠시 후 다시 시도해 주세요.');
}
} else {
Warning.show('서버와 통신하지 못하였습니다. 잠시 후 다시 시도해 주세요.');
}
}
};
xhr.send(formData);
});
결과