Spring Boot/구현해보기

비밀번호 재설정 구현2

xowoony 2022. 11. 13. 10:50

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);
});

 


결과