Spring & Springboot/올인원 스프링 프레임워크

전자 도서관 프로젝트 - 비밀번호 분실 처리 구현

YJ_ma 2023. 12. 2. 22:13

비밀번호 찾기 화면으로 이동

<find password> 버튼은 로그인 화면(login_form.jsp)에 있다.

<a href="<c:url value='/user/member/findPasswordForm' />">find password</a>

 

비밀번호를 찾는 <find password> 버튼은 /user/member/findPasswordForm에 링크되어 있으므로 UserMemberController 컨트롤러에 메서드를 만들고 매핑한다.

// 비밀번호 찾기
@GetMapping("/findPasswordForm")
public String findPasswordForm() {
    System.out.println("[UserMemberController] findPasswordForm()");

    String nextPage = "user/member/find_password_form";

    return nextPage;
}

 

비밀번호 찾기

비밀번호 찾기 화면은 find_password_form.jsp로 비밀번호 찾기에 필요한 계정 아이디, 이름, 메일 주소를 입력하는 양식이 다음과 같이 구성되어 있다.

· 비밀번호 찾기에 필요한 정보(아이디, 이름, 메일주소)가 전송되는 서버 주소는 /user/member/findPasswordConfirm이고, 전송 방식은 post이다.

<form action="<c:url value='/user/member/findPasswordConfirm' />" name="find_password_form" method="post">

    <input type="text" name="u_m_id" placeholder="INPUT USER ID."> <br>
    <input type="text" name="u_m_name" placeholder="INPUT USER NAME."> <br>
    <input type="text" name="u_m_mail" placeholder="INPUT USER MAIL."> <br>
    <input type="button" value="find password" onclick="findPasswordForm();"> 
    <input type="reset" value="reset">

</form>

 

컨트롤러 기능 구현

서버에서 비밀번호 찾기 요청을 처리하기 위해서 UserMemberController에 findPasswordConfirm()을 선언하고 클라이언트의 요청(/user/member/findPasswordConfirm)을 매핑한다.

// 비밀번호 찾기 확인
@PostMapping("/findPasswordConfirm")
public String findPasswordConfirm(UserMemberVo userMemberVo) {
    System.out.println("[UserMemberController] findPasswordConfirm()");

    String nextPage = "user/member/find_password_ok";

    int result = userMemberService.findPasswordConfirm(userMemberVo);

    if (result <= 0)
        nextPage = "user/member/find_password_ng";

    return nextPage;
}

 

서비스 기능 구현

컨트롤러에서 지시한 업무를 처리하기 위해서 UserMemberService 서비스에 findPasswordConfirm()을 다음과 같이 선언한다.

public int findPasswordConfirm(UserMemberVo userMemberVo) {
    System.out.println("[UserMemberController] findPasswordConfirm()");

    UserMemberVo selectedUserMemberVo = userMemberDao.selectUser(
            userMemberVo.getU_m_id(),
            userMemberVo.getU_m_name(),
            userMemberVo.getU_m_mail());

    int result = 0;

    if (selectedUserMemberVo != null) {

        String newPassword = createNewPassword();
        result = userMemberDao.updatePassword(userMemberVo.getU_m_id(), newPassword);

        if (result > 0)
            sendNewPasswordByMail(userMemberVo.getU_m_mail(), newPassword);
    }
    return result;
}

 

이제 새로운 비밀번호를 생성하고 메일을 발송한느 createNewPassword()와 sendNewPasswordByMail()을 선언해준다.

- 관리자 새로운 비밀번호 생성 메서드와 동일하다.

@Autowired
JavaMailSenderImpl javaMailSenderImpl;
..생략..

private String createNewPassword() {
    System.out.println("[UserMemberService] createNewPassword()");

    char[] chars = new char[] {
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
            'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
            'u', 'v', 'w', 'x', 'y', 'z'};

    StringBuffer stringBuffer = new StringBuffer();
    SecureRandom secureRandom = new SecureRandom();
    secureRandom.setSeed(new Date().getTime());

    int index = 0;
    int length = chars.length;
    for (int i = 0; i < 8; i++) {
        index = secureRandom.nextInt(length);

        if (index % 2 == 0)
            stringBuffer.append(String.valueOf(chars[index]).toUpperCase());
        else
            stringBuffer.append(String.valueOf(chars[index]).toLowerCase());
    }

    System.out.println("[UserMemberService] NEW PASSWORD: " + stringBuffer.toString());

    return stringBuffer.toString();
}

private void sendNewPasswordByMail(String toMailAddr, String newPassword) {
    System.out.println("[UserMemberService] sendNewPasswordByMail()");

    final MimeMessagePreparator mimeMessagePreparator = new MimeMessagePreparator() {

        @Override
        public void prepare(MimeMessage mimeMessage) throws Exception {
            final MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
            mimeMessageHelper.setTo("mayoonju@gmail.com");
            mimeMessageHelper.setSubject("[한국도서관] 새비밀번호 안내입니다.");
            mimeMessageHelper.setText("새비밀번호: " + newPassword, true);
        }
    };
    javaMailSenderImpl.send(mimeMessagePreparator);
}

 

DAO 기능 구현

서비스에서 지시한 업무를 처리하기 위해 UserMemberDao에 selectUser()를 다음과 같이 코딩한다.

public UserMemberVo selectUser(String u_m_id, String u_m_name, String u_m_mail) {
    System.out.println("[UserMemberDao] selectUser()");

    String sql = "SELECT * FROM tbl_user_member "
            + "WHERE u_m_id = ? AND u_m_name = ? AND u_m_mail = ?";

    List<UserMemberVo> userMemberVos = new ArrayList<UserMemberVo>();

    try {
        userMemberVos = jdbcTemplate.query(sql, new RowMapper<UserMemberVo>() {
            @Override
            public UserMemberVo mapRow(ResultSet rs, int rowNum) throws SQLException {

                UserMemberVo userMemberVo = new UserMemberVo();

                userMemberVo.setU_m_no(rs.getInt("u_m_no"));
                userMemberVo.setU_m_id(rs.getString("u_m_id"));
                userMemberVo.setU_m_pw(rs.getString("u_m_pw"));
                userMemberVo.setU_m_name(rs.getString("u_m_name"));
                userMemberVo.setU_m_gender(rs.getString("u_m_gender"));
                userMemberVo.setU_m_mail(rs.getString("u_m_mail"));
                userMemberVo.setU_m_phone(rs.getString("u_m_phone"));
                userMemberVo.setU_m_reg_date(rs.getString("u_m_reg_date"));
                userMemberVo.setU_m_mod_date(rs.getString("u_m_mod_date"));

                return userMemberVo;
            }
        }, u_m_id, u_m_name, u_m_mail);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return userMemberVos.size() > 0 ? userMemberVos.get(0) : null;
}

 

이어서 데이터베이스에서 새 비밀번호를 업데이트할 때 이용되는 메서드 updatePassword() 메서드를 생성한다.

public int updatePassword(String u_m_id, String newPassword) {
    System.out.println("[UserMemberDao] updatePassword()");

    String sql = "UPDATE tbl_user_member SET "
            + "u_m_pw = ?, u_m_mod_date = NOW() "
            + "WHERE u_m_id = ?";

    int result = -1;

    try {
        result = jdbcTemplate.update(sql, passwordEncoder.encode(newPassword), u_m_id);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result;
}

 

새로운 비밀번호 생성 및 데이터베이스 업데이트 그리고 새로운 비밀번호 메일 발송까지 모든 기능을 테스트해본다.