나의개발일지

새 비밀번호 생성 with. e-mail 본문

프로젝트/전자도서관 프로젝트

새 비밀번호 생성 with. e-mail

아. 이렇게 하면 될거 같은데.. 2024. 1. 7. 00:35
728x90


비밀번호를 잊어버리면 DB관리자도 암호화된 비밀번호를 알 수 없어서 새로운 비밀번호를 생성후 DB에 업데이트하고 메일로 발송 한다.

프로젝트를 시작하고, 로그인버튼을 클릭한후 find password 버튼을 눌러서 새로운 비밀번호 찾기 절차가 실행된다.


비밀번호 찾기 화면

 

◆ 메일 전송 완료


메일 발송 모듈 설정

 

스프링에서는 메일 발송을 위해 JavaMailSenderImpl을 이용한다.

JavaMailSenderImpl을 사용하기 위해 pom.xml과 Ioc컨테이너에 등록하는 과정이 필요하다.

 

<pom.xml>

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>

 

<mail-context.xml>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.3.xsd">

    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="smtp.gmail.com"/>
        <property name="port" value="587"/>
        <property name="username" value="#이메일 주소"/>
        <property name="password" value="#생성된 앱 비밀번호"/>
        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtp.auth">true</prop>
                <prop key="mail.smtp.starttls.enable">true</prop>
            </props>
        </property>

    </bean>
	
</beans>

 

<web.xml>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    /WEB-INF/spring/root-context.xml
    /WEB-INF/spring/jdbc-context.xml
    /WEB-INF/spring/security-context.xml
    /WEB-INF/spring/mail-context.xml
    /WEB-INF/spring/file-context.xml
    </param-value>
</context-param>

 

Gmail의 앱 비밀번호는 해당 포스트를 참고 바란다.

https://cacaodotori.tistory.com/22

 

Gmail 2단계 인증 및 앱 비밀번호 생성하기

앱 비밀번호는 일반적으로 Gmail 계정을 앱이나 디바이스에 연결할 때 사용된다. 특히 보안 앱 또는 이메일 클라이언트와 같은 앱에서 Gmail 계정을 사용할 때 필요하다. 1. 크롬에서 구글 계정으로

cacaodotori.tistory.com


비밀번호 찾기 메일 발송 과정 구현

 

1. JSP페이지

form태그를 이용해서 아이디와, 이름, 이메일정보를 받아서 버튼이 눌릴때 Cotroller에게 정보들과 "/admin/member/findPasswordConfirm" 신호를 전달한다.

※ 이때 post방식으로 전달한다.

<div class="find_password_form">

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

        <input type="text" name="a_m_id" placeholder="INPUT ADMIN ID."> <br>
        <input type="text" name="a_m_name" placeholder="INPUT ADMIN NAME."> <br>
        <input type="text" name="a_m_mail" placeholder="INPUT ADMIN MAIL."> <br>
        <input type="button" value="find password" onclick="findPassword();"> 
        <input type="reset" value="reset">

    </form>
</div>

 

2. Controller

컨트롤러 부분에서 서비스에 있는 findPasswordConfirm을 호출하여 결과값에 저장후 다음으로 내보낼 페이지를 지정한다.

※ 호출할때 "adminMemberVo"가 사용된다.

@PostMapping("/findPasswordConfirm")
public String findPasswordConfirm(AdminMemberVo adminMemberVo) {
    System.out.println("[AdminMemberController] findPasswordConfirm");

    String nextPage = "admin/member/find_password_ok";

    int result = adminMemberService.findPasswordConfirm(adminMemberVo);

    if (result > 0)
        nextPage = "admin/member/find_password_ng";

    return nextPage;


}

 

3. Service

● findPasswordConfirm 메서드

  • DAO에 selectAdmin메서드를 실행하여 해당 id, name, mail을 사용하여 유저정보를 받아온다.
  • 만약 유저가 있으면 createPassword 메서드를 실행하여 새로운 비밀번호를 만든후
  • DAO에 updatePassword 메서드를 실행하여 DB에 새로운 비밀번호로 바꾼다.
  • 새로운 비밀번호를 메일로 발송 한다.

 

public int findPasswordConfirm(AdminMemberVo adminMemberVo) {
    System.out.println("[AdminMemberService] findPasswordConfirm");

    AdminMemberVo selectedAdminMemberVo = adminMemberDao.selectAdmin(adminMemberVo.getA_m_id(), adminMemberVo.getA_m_name(), adminMemberVo.getA_m_mail());

    int result = 0;

    if (selectedAdminMemberVo != null) {
        //등록된 id이므로 새 비밀번호 생성
        String newPassword = createPassword();

        //데이터베이스에 업데이트
        result = adminMemberDao.updatePassword(adminMemberVo.getA_m_id(),newPassword);

        //새 비밀번호를 메일로 발송
        sendNewPasswordByMail(adminMemberVo.getA_m_mail(), newPassword);
    }
    return result;
}

 

● createPassword 메서드

  • 0 ~ 9 까지, a ~ z 까지 새로운 문자 배열 chars을 생성한다.
  • 랜덤설정에 사용하는 Seed는 현재 시간이다.
  • 비밀번호는 총 8자리이며 secureRandom을 이용하여 랜덤으로 새로운 비밀번호가 될 chars의 idx를 가져온다.
  • 만약 idx가 짝수라면 stringBuffer에 toUpperCase()를 이용하여 대문자로 추가하고
  • 홀수라면 소문자로 추가한다.
  • 새로운 비밀번호를 출력후 리턴한다.

 

private String createPassword() {
    System.out.println("[AdminMemberService] createPassword");

    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','n','m','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("NEW PASSWORD : " + stringBuffer.toString());

    return stringBuffer.toString();
}

 

● sendNewPasswordByMail 메서드

  • JavaMailSenderImpl을 사용하기위해 @Autowired를 사용하여 객체주입을 해야한다.
  • 익명클래스를 사용하여 MimeMessagePreparator 인스턴스를 초기화 한다.
  • (MimeMessagePreparator는 MIME 메시지를 준비하기 위한 콜백 인터페이스이다.)
  • MIME메시지 전송을 간단화 시키는 helper 인스턴스를 초기화 한다.
  • 수신자 메일, 제목, 내용(새로운 비밀번호)을 설정한다.
  • send메서드를 이용하여 발송한다.

 

@Autowired
JavaMailSenderImpl javaMailSenderImpl;

//생략

private void sendNewPasswordByMail(String a_m_mail, String newPassword) {

    final MimeMessagePreparator mimeMessagePreparator =
            new MimeMessagePreparator() {

                @Override
                public void prepare(MimeMessage mimeMessage) throws Exception {
                    final MimeMessageHelper helper =
                            new MimeMessageHelper(mimeMessage, true, "utf-8");

                    helper.setTo(a_m_mail);
                    helper.setSubject("[한국 도서관] 새 비밀번호 발송");
                    helper.setText("새 비밀번호는 :" + newPassword, true);

                }
            };

            javaMailSenderImpl.send(mimeMessagePreparator);
}

 

4. DAO

● selectAdmin 메서드

※여기서 전에 구현한 메서드에서 selectAdmin메서드가 있지만 매서드 오버로딩을 활용하였다.

id, name, mail값을 확인하여 유저정보를 DB에서 가져온다.

 

public AdminMemberVo selectAdmin(String a_m_id, String a_m_name, String a_m_mail) {

    String sql = "SELECT * FROM tb1_admin_member WHERE a_m_id=? AND " +
                 "a_m_name=? AND a_m_mail=?";
    List<AdminMemberVo> adminMemberVos = new ArrayList<AdminMemberVo>();

    adminMemberVos = jdbcTemplate.query(sql, new RowMapper<AdminMemberVo>() {

        @Override
        public AdminMemberVo mapRow(ResultSet rs, int rowNum) throws SQLException {
            AdminMemberVo adminMemberVo = new AdminMemberVo();
            adminMemberVo.setA_m_no(rs.getInt("a_m_no"));
            adminMemberVo.setA_m_approval(rs.getInt("a_m_approval"));
            adminMemberVo.setA_m_id(rs.getString("a_m_id"));
            adminMemberVo.setA_m_pw(rs.getString("a_m_pw"));
            adminMemberVo.setA_m_name(rs.getString("a_m_name"));
            adminMemberVo.setA_m_gender(rs.getString("a_m_gender"));
            adminMemberVo.setA_m_part(rs.getString("a_m_part"));
            adminMemberVo.setA_m_position(rs.getString("a_m_position"));
            adminMemberVo.setA_m_mail(rs.getString("a_m_mail"));
            adminMemberVo.setA_m_phone(rs.getString("a_m_phone"));
            adminMemberVo.setA_m_reg_date(rs.getString("a_m_reg_date"));
            adminMemberVo.setA_m_mod_date(rs.getString("a_m_mod_date"));
            return adminMemberVo;
        }
    }, a_m_id, a_m_name, a_m_mail);

    return (adminMemberVos.size() > 0)? adminMemberVos.get(0) : null;
}

 

● updatePassword 메서드

새롭게 받은 비밀번호를 passwordEncoder를 활용해 암호화하여 DB에 업데이트 한다.

 

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

    String sql = "UPDATE tb1_admin_member SET a_m_pw = ?, a_m_mod_date = NOW() WHERE a_m_id = ?";

    int result = -1;

    result = jdbcTemplate.update(sql, passwordEncoder.encode(newPassword), a_m_id);

    return result;
}

 

 

728x90
반응형

'프로젝트 > 전자도서관 프로젝트' 카테고리의 다른 글

도서등록  (0) 2024.01.07
계정 수정  (2) 2023.12.28
로그인, 로그아웃  (0) 2023.12.24
회원가입  (0) 2023.11.21
개발환경 세팅  (0) 2023.11.14