플로우는 아래와 같다.
1. 아이디와 이메일을 입력한다.
2. 입력한 값이 회원테이블에 있는 지 확인한다.
3. 회원이 존재할 경우, 임시 비번을 생성해서 회원의 이메일로 전송한다.
4. 마지막으로 사용자는 임시 비번으로 로그인을 시도한다.
기존에 참고했던 사이트는 alert()로 알려주기 위해서
PrintWriter writer = resp.writer();를 사용했다.
나는 일단 이메일을 전송하는 것까지 했다.
alert() 처리를 어떻게 할 지가 고민이다.
폴더 전체 구조는 아래와 같다.
@Controller
@RequestMapping("/member")
public class MemberController {
@Autowired
BCryptPasswordEncoder passwordEncoder;
//주입
@Autowired
MemberServiceImpl service;
@RequestMapping(value = "/findpw", method = RequestMethod.GET)
public String getView() {
return "findpw";
}
@RequestMapping(value = "/findpw", method = RequestMethod.POST)
public void findPwPOST(@ModelAttribute User user, HttpServletResponse response) throws Exception {
if (service.isUserPresent(user)) //일치하는 유저 존재.
service.doPasswordFind(user); //비밀찾기 기능을 수행한다.
}
@GetMapping("/checkPwd")
public void testRequest() {
System.out.println("compare::: " + passwordEncoder.matches("vccndhrhuljp","$2a$10$BZ8qvRDBeoen5wINU8VT.eM6mZXIGKB3lVFxLZauDTDmAL6LupH0G"));
}
}
/findpw에서 jsp 단에서 보내준 ajax에 의한 요청 정보로
비밀찾기 기능을 수행한다.
/checkPwd단에서는 입력한 임시 비번과 db에 저장된 인코딩된 비밀번호가 일치하는 지 확인하는 메서드다.
중요한 서비스로 가보자.
//디비를 임시 비번으로 업데이트 한다.
public void updateWithTempPwd (User user) throws Exception {
user.setPwd(passwordEncoder.encode(user.getPwd()) + ""); //비밀번호를 먼저 인코딩한다.
dao.updateWithTempPwd(user);
}
// id + email을 가진 유저가 존재하는 지 여부를 체크하는 메서드
public boolean isUserPresent (User user) throws Exception {
return dao.checkExistingUser(user) == 1;
}
//난수를 만들어서 메일도 보내고 업데이트 메서드한테도 전달한다.
public void doPasswordFind(User user) throws Exception {
//1. 난수를 만든다.
String pw = "";
for (int i = 0; i < 12; i++) {
pw += (char) ((Math.random() * 26) + 97);
};
user.setPwd(pw); // 임시 비번을 유저에 저장한다.
//1. 이메일에 난수를 담아 전송한다.
sendEmail(user.getPwd(), user.getEmail());
//2. 인코딩해서 디비를 업데이트 친다.
updateWithTempPwd(user); //디비로 업데이트 친다.
}
sendEmail(user.getPwd(), user.getEmail());은
저번에 포스팅했던 이메일 전송 메서드에 + 하드코딩했던 수신자와 난수를 파라미터로 받아오도록 설정했다.
대부분 설명은 주석에 있다.
다만 doPasswordFind(User user) 메서드가 단일 책임 원칙을 위반했다.
난수를 만드는 함수 하나 따로 만들고, 그걸 String result 식으로 담아서 result를 가지고 sendEmail와 updateWithTempPwd에 전달하는 메서드를 따로 만드는 편이 나았을 것 같다.
dao와 쿼리의 경우 아래처럼 했다.
select count(*) from member where userid = #{userId} and email = #{email}
주의할 점
dao 만들 때 메서드 이름 일치하게 주의하기.
예: 메서드명과 session.selectOne(nameSpace +"메서드명", User user)이 같게 하자.
jsp화면은 다음과 같다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(function(){
$("#findBtn").click(function(){
$.ajax({
url : "/member/findpw",
type : "POST",
data : {
id : $("#id").val(),
email : $("#email").val()
},
success : function(result) {
alert(result);
},
})
});
})
</script>
<style type="text/css">
.mybtn{
width:150px;
height:40px;
padding:0;
display:inline;
border-radius: 4px;
background: #212529;
color: #fff;
margin-top: 20px;
border: solid 2px #212529;
transition: all 0.5s ease-in-out 0s;
}
.mybtn:hover .mybtn:focus {
background: white;
color: #212529;
text-decoration: none;
}
</style>
<title>비밀번호 찾기</title>
</head>
<body>
<div class="w3-content w3-container w3-margin-top">
<div class="w3-container w3-card-4 w3-auto" style="width: 382px;height: 456.3px;">
<div class="w3-center w3-large w3-margin-top">
<h3>비밀번호 찾기</h3>
</div>
<div>
<p>
<label>아이디</label>
<input class="w3-input" type="text" id="id" name="id" placeholder="회원가입한 아이디를 입력하세요" required>
</p>
<p>
<label>이메일</label>
<input class="w3-input" type="text" id="email" name="email" placeholder="회원가입한 이메일주소를 입력하세요" required>
</p>
<p class="w3-center">
<button type="button" id="findBtn" class="w3-button w3-hover-white w3-ripple w3-margin-top w3-round mybtn">찾기</button>
<button type="button" onclick="history.go(-1);" class="w3-button w3-hover-white w3-ripple w3-margin-top w3-round mybtn">로그인으로</button>
</p>
</div>
</div>
</div>
</body>
</html>
참고사이트:
https://kimvampa.tistory.com/m/93
https://sowon-dev.github.io/2020/10/31/201101findpw/
https://kimvampa.tistory.com/m/93