The Kkang's man

[WANT] 2. 비밀번호 찾기(메일X) - Spring Framework MVC 본문

Project : WANT

[WANT] 2. 비밀번호 찾기(메일X) - Spring Framework MVC

정낑깡 2021. 4. 27. 19:00

목 차


1. 구현화면
2. 구조
3. 코드

1. 구현화면

1-1. 비밀번호 찾기 실패

1-2 비밀번호 찾기 성공

비밀번호 찾기를 메일로 전송하는 방식이 아닌, 비밀번호 절반을 직접 나타내주는 형태로 구현했다.

 

2. 구조

    ① View 페이지(pwFindForm.jsp)에 아이디와 메일을 입력 후 비밀번호 찾기 버튼을 클릭

    ② 입력된 값은 Controller(UserController.java)에 제출된다.

    ③ 제출된 값은 Controller에서 UserTO의 변수에 담고 UserDAO의 메서드를 호출한다.

    ④ mapper(mapper.xml)의 sql문을 통해 ID와 메일, 암호화되어있는 비밀번호를 Select한다.

    ⑤ 암호화되어 있는 비밀번호의 암호화를 풀고 그 절반을 *로 변환시킨다.

    ⑥ 이 때 리턴되는 값을 UserDAO에서 Controller로 보내준다.

     Controller에서 받은 flag 값은 다시 pwFindForm_ok.jsp로 보내지고 결과 창을 보여준다.

    

 

기본적으로 구조의 흐름은 지난 회원가입에서 작성했던 구조와 크게 다르지 않으니

조금 더 자세한 흐름을 보고 싶다면 아래 링크 확인을 추천한다.

[WANT] 1. 회원가입 - Spring Framework MVC

 

[WANT] 1. 회원가입 - Spring Framework MVC

목차 1. 구현화면 2. 구조 3. DB 4. 코드 구성 1. 구현화면 2. 구조 먼저 구조를 간단하게 요약하면 ① View 페이지(signupForm.jsp)에 값을 입력 후 회원가입 버튼을 클릭 ② 입력된 값은 Controller(UserContro..

kkangsman.tistory.com

3. 코드

3-1. pwFindForm.jsp ( views/user/pwFindForm.jsp )

# jsp 전체 코드

더보기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>비밀번호 찾기</title>

<script>
	
	window.onload = function() {
		document.getElementById('submit').onclick = function() {
			
			if ( document.pfrm.id.value.trim() == '' ) {
				alert( 'ID를 입력해주세요' );
				return false;
			}
			if ( document.pfrm.mail.value.trim() == '' ) {
				alert( '메일을 입력해주세요' );
				return false;
			}
			document.pfrm.submit();
		}
	}
</script>

</head>
<body>

<div class="pwFind-form">
    <form action="pwFindForm_ok.do" method="post" class="form-horizontal" name="pfrm">
	
      	<div class="row">
        	<div align="center">
			<h2>비밀번호 찾기</h2>
		</div>	
      	</div>			
        <div class="form-group row">
		<label class="col-form-label col-4">아이디</label>
		<div class="col-8">
			<input type="text" class="form-control" name="id" placeholder="아이디를 입력하세요." required="required">
		</div>        	
        </div>

	<div class="form-group row">
		<label class="col-form-label col-4">이메일</label>
		<div class="col-8">
			<input type="text" class="form-control" name="mail" placeholder="메일을 입력하세요." required="required">
		</div>        	
        </div>
	<div class="form-group row">
		<button type="submit" id="submit" class="btn btn-primary btn-lg">비밀번호 찾기</button>
	</div>		

    </form>
</div>
</body>
</html>


# ID / Mail 입력란

더보기
<form action="pwFindForm_ok.do" method="post" class="form-horizontal" name="pfrm">
	
	<div class="row">
		<div align="center">
			<h2>비밀번호 찾기</h2>
		</div>	
	</div>			
	<div class="form-group row">
		<label class="col-form-label col-4">아이디</label>
		<div class="col-8">
			<input type="text" class="form-control" name="id" placeholder="아이디를 입력하세요." required="required">
		</div>        	
	</div>

	<div class="form-group row">
		<label class="col-form-label col-4">이메일</label>
		<div class="col-8">
			<input type="text" class="form-control" name="mail" placeholder="메일을 입력하세요." required="required">
		</div>        	
	</div>
	<div class="form-group row">
		<button type="submit" id="submit" class="btn btn-primary btn-lg">비밀번호 찾기</button>
	</div>		
</form>

ID와 Mail의 값을 입력받고 비밀번호 찾기 버튼을 누르면 id 값인 submit과 form 태그의 namepfrm을 통해 값이 모두 입력되었는지 script에서 검사한다.

 

# 검사

더보기
<script type="text/javascript">
	
	window.onload = function() {
		document.getElementById('submit').onclick = function() {
			
			if ( document.pfrm.id.value.trim() == '' ) {
				alert( 'ID를 입력해주세요' );
				return false;
			}
			if ( document.pfrm.mail.value.trim() == '' ) {
				alert( '메일을 입력해주세요' );
				return false;
			}
			document.pfrm.submit();
		}
	}
</script>

검사는 <head>의 JavaScript에서 onclick 이벤트 처리를 통해 이루어진다.

Form( pfrm ) 안의 id의 value가 비어있을 때( trim() == '' )

ID를 입력해 달라는 알림창을 띄우고 false를 리턴해 아무 값도 제출하지 않는다.

 

3-2. UserController( controller/UserController.java )

# UserController 전체 코드

더보기
@Controller
public class UserController {

	@Autowired
	private UserDAO userDao;

	@RequestMapping(value = "/pwFindForm_ok.do")
	public String pwFindForm_ok(HttpServletRequest request, HttpServletResponse response) throws Exception {
		int flag = 2;
		
		UserTO userTo = new UserTO();

		String id = request.getParameter("id");
		String mail = request.getParameter("mail");
		
		userTo.setId(id);
		userTo.setMail(mail);
		
		int result_lookup = userDao.pwFind_Lookup(userTo);
		if (result_lookup == 1) { // 회원있음
//			System.out.println("lookup : " + result_lookup);
			
			//메일확인
			int pwFind_ok = userDao.pwFind_ok(userTo);
//			System.out.println("pwFind_ok : " + pwFind_ok);
		
			if (pwFind_ok == 1) { // 메일 일치
				userTo = userDao.pwFind_select(userTo);
				
				// 암호화 된 비밀번호 풀어주는 작업
				String key = "secret Key";
				String realPwd = userDao.pwFindDecry(userTo).getPwd();
				String decryPwd = userDao.decryptAES(realPwd, key);
				
				// 비밀번호 길이를 2로 나누어서
				int pwdSize = decryPwd.length()/2;
//				System.out.println( pwdSize );
				
				String resultPwd_1 = decryPwd.substring(0, pwdSize );
				
				// 뒤의 절반은 *로 표시
				String tmp = "";
				if (pwdSize%2 ==1) { // 홀수인 경우 * 한개 더 추가
					for( int i=0; i<pwdSize+1; i++ ) {
						tmp += "*";
					}
				} else {
					for( int i=0; i<pwdSize; i++ ) {
						tmp += "*";
					}
				}
				String resultPwd = resultPwd_1 + tmp;
				
				flag = 0;
				
				// 표시될 비밀번호를 pwd에 담음
				userTo.setPwd(resultPwd);
//				System.out.println("getPwd : " + userTo.getPwd());
				
				request.setAttribute("pwd", userTo.getPwd());
				request.setAttribute("id", id);
				
			} else if(pwFind_ok==0) { // 메일x
				flag = 1;
				
			} else {	// 기타오류
				flag = 3;
			}
		} else if (result_lookup == 0) { // 회원없음
			flag = 2;
		} else { // 기타오류
			flag = 3;
		}
		request.setAttribute("flag", flag);

		return "user/pwFindForm_ok";
	}

}

 

# JSP에서 보낸 값 처리

더보기

JSP에서 제출한 Id와 Mail을 Controller의 userTo에 담는다.

UserTO userTo = new UserTO();

		String id = request.getParameter("id");
		String mail = request.getParameter("mail");
		
		userTo.setId(id);
		userTo.setMail(mail);

 

3-3. UserDAO(model1/user/UserDAO.java)

더보기
	//회원있는지 여부 확인
	public Integer pwFind_Lookup( UserTO userTo ) {
		int result = sqlSession.selectOne( "pwFind_lookup", userTo );
		return result;
	}
	
	//회원 메일 있는지 확인
	public int pwFind_ok( UserTO userTo ) {
		int result = sqlSession.selectOne( "pwFind_ok", userTo );
		return result;
	}
	
	//회원 비밀번호 가져오기
	public UserTO pwFind_select( UserTO userTo ) {
		UserTO to = sqlSession.selectOne("pwFind_select", userTo);
		return to;
	}

 

3-4. mapper.xml ( resources/mappers/mapper.xml )

# 회원이 있는지 여부 확인

더보기

db에 있는 id와 유저가 입력한 id를 비교하여 id가 있으면 1, 없으면 0 출력

	<select id="pwFind_lookup"
		parameterType="com.exam.model1.user.UserTO" resultType="Int">
		select count( id )
		from user
		where id = #{ id };
	</select>

 

# 메일 확인

더보기

입력받은 id와 mail 모두 일치하는 컬럼의 수를 찾는다.

	<select id="pwFind_ok" parameterType="com.exam.model1.user.UserTO"
		resultType="Int">
		select count(id)
		from user
		where id = #{id} and mail = #{mail}
	</select>

id가 PK 이므로 결과는 반드시 1 혹은 0이 출력된다.

따라서 올바른 id와 mail을 입력했다면 1이 출력된다.

 

# 비밀번호 조회

더보기

id와 mail이 일치하는 컬럼의 비밀번호를 조회한다.

	<select id="pwFind_select"
		parameterType="com.exam.model1.user.UserTO"
		resultType="com.exam.model1.user.UserTO">
		select pwd
		from user
		where id = #{id} and mail = #{mail}
	</select>

 

3-5. UserController( controller/UserController.java)

# 비밀번호 뒷자리 절반을 *로 치환

더보기

먼저 회원이 있는지를 확인

		int result_lookup = userDao.pwFind_Lookup(userTo);
		if (result_lookup == 1) { // 회원있음

 

회원이 있다면 메일이 일치하는지 확인 후 메일이 일치한다면 비밀번호를 불러온다

			int pwFind_ok = userDao.pwFind_ok(userTo);
			if (pwFind_ok == 1) { // 메일 일치
				userTo = userDao.pwFind_select(userTo);

 

비밀번호가 암호화 되어 있으므로 암호화를 풀어주는 과정을 거친다

				String key = "secret Key";
				String realPwd = userDao.pwFind_select(userTo).getPwd();
				String decryPwd = userDao.decryptAES(realPwd, key);

 

암호화가 풀린 비밀번호의 길이를 2로 나누고

				int pwdSize = decryPwd.length()/2;

 

그 뒤의 절반을 *로 치환한다. 이 때 비밀번호가 홀수인 경우 * 하나가 누락되기 때문에 홀수인 경우엔 * 하나를 추가해준다.

				String resultPwd_1 = decryPwd.substring(0, pwdSize );
				
				// 뒤의 절반은 *로 표시
				String tmp = "";
				if (pwdSize%2 ==1) { // 홀수인 경우 * 한개 더 추가
					for( int i=0; i<pwdSize+1; i++ ) {
						tmp += "*";
					}
				} else {
					for( int i=0; i<pwdSize; i++ ) {
						tmp += "*";
					}
				}
				String resultPwd = resultPwd_1 + tmp;

 

이 과정이 모두 완료되면 flag를 0으로 지정해주고 나타낼 비밀번호를 pwd에 담는다.

				flag = 0;
				
				userTo.setPwd(resultPwd);
				
				request.setAttribute("pwd", userTo.getPwd());
				request.setAttribute("id", id);

 

flag는 모두 다음과 같다

if(result_lookup ==1) { // 회원이 있고
	if(pwFind_ok == 1) { // 메일이 일치하면
    	flag = 0;
	} else if(pwFind_ok==0) { // 메일이 다른 경우
		flag = 1;	
	} else {	// 기타오류
		flag = 3;
	}
} else if (result_lookup == 0) { // 회원이 없는 경우
	flag = 2;
} else { // 기타오류
	flag = 3;
}
request.setAttribute("flag", flag);

return "user/pwFindForm_ok";

flag 분류가 모두 완료되면 다시 pwFindForm_ok로 보낸다.

 

3-6. pwFindForm_ok.jsp ( views/user/pwFindForm_ok.jsp )

# 결과 분류

더보기
<%@ page import="com.exam.model1.user.UserTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	request.setCharacterEncoding("utf-8");
	

	String id = (String)request.getAttribute("id");
	String pwd = (String)request.getAttribute("pwd");
	
	int flag = (Integer)request.getAttribute( "flag" );
	out.println( " <script type='text/javascript'> " );

	if( flag == 0 ) {	// 아이디, 메일 일치
		out.println( " alert('비밀번호는"+pwd+"입니다.')" );
		out.println( " location.href='./loginForm.do'" );
		
	} else if( flag == 1 ) {	//메일 틀림
		out.println( " alert('메일을 다시 확인해주세요.'); " );
		out.println( " history.back(); " );
	} else if( flag == 2 ) {	//회원정보없음
		out.println( " alert('회원정보가 없습니다. 회원가입해주세요.'); " );
		out.println( " history.back(); " );
	} else {					//기타 에러났을 때
		out.println( " alert('다시 입력해주세요.'); " );
		out.println( " history.back(); " );
	}
	out.println( " </script> " );

%>

앞에서 분류해 준 flag에 따라 나타낼 결과창을 표현해준다.

 

Comments