아이디 비밀번호 찾기 기능은 크게 User 모델, UserService 및 UserController클래스, 그리고 프론트엔드 html 및 css, js파일을 사용하여 구성할수 있습니다
1. User.java 수정
resetToken 추가
사용자가 비밀번호를 잊었을때 , 비밀번호 재설정 링크 생성에 사용되는 고유 토큰을 저장하는데 사용됩니다.
토큰은 보통 UUID 방식으로 생성되며, 아이디 / 비밀번호 찾기 요청이 들어오면 이토큰을 생성하여 User객체에 저장하고 사용자의 이메일로 해당토큰을 포함한 링크를 보냅니다.
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User implements UserDetails {
// ...[기존코드]
@Column(length = 64)
private String resetToken; // 비밀번호 재설정을 위한 토큰
// ...[생략된 UserDetails 구현 관련 메서드]
}
2. UserService.java 수정
createPasswordResetTokenForUser 메소드 추가
public String createPasswordResetTokenForUser(User user) {
String token = UUID.randomUUID().toString();
user.setResetToken(token);
userRepository.save(user);
return token;
}
사용자가 비밀번호 재설정 요청을 했을때, 토큰을 생성합니다. 이 토큰을 통해 사용자를 식별합니다.
UUID.randomUUID().toString() 방법을 사용하여 무작위 토큰을 생성합니다.
생성된 토큰을 User 엔티티 resetToken 필드에 저장하고 db에 업데이트합니다.
sendPasswordResetEmail 메소드 추가
public void sendPasswordResetEmail(User user, String token) throws MessagingException {
// 현재 시간 설정
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
String formattedNow = now.format(formatter);
// 비밀번호 변경 링크
String resetLink = "http://localhost:8080/changePw?token=" + token;
// 이메일 메시지 구성
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
helper.setTo(user.getEmail());
helper.setSubject("코와사 비밀번호 재설정 메일");
// HTML 메시지 설정
String htmlMsg = "<p>안녕하세요.</p>" +
"<p>회원님은 " + formattedNow + "에 비밀번호 찾기 요청을 하셨습니다.</p>" +
"<p>코와사는 특정 회원의 비밀번호를 확인할 수 없기 때문에 아래 버튼을 통해 비밀번호를 초기화해주세요.</p>" +
"<p>회원 아이디: " + user.getUsername() + "</p>" +
"<a href='" + resetLink + "' style='color: white; text-decoration: none; padding: 10px 20px; background-color: #1a73e8; border-radius: 5px; display: inline-block;'>비밀번호 변경</a>";
// HTML 형식으로 메시지를 설정합니다.
helper.setText(htmlMsg, true);
// 메일 발송
mailSender.send(message);
}
사용자에게 아이디확인 및 비밀번호 재설정 링크를 포함한 이메일을 보내어 비밀번호를 재설정할수 있도록 할수 있습니다. JavaMailSender 이메일발송서비스를 사용하여 이메일을 구성하고 발송합니다.
이메일 내용에는 아이디가 출력되도록 작성하고 비밀번호 재설정페이지로 연결하는 링크를 포함시킵니다.
링크를 클릭하면 사용자는 비밀번호를 재설정할수 있는 웹페이지changPw.html로 redirect됩니다.
changeUserPassword 메소드 추가
public void changeUserPassword(User user, String newPassword) {
user.setPassword(passwordEncoder.encode(newPassword)); // 비밀번호 암호화
userRepository.save(user);
}
사용자가 링크로 접속하여 입력한 새로운비밀번호를 db에 저장합니다.
PasswordEncoder을 사용하여 새비밀번호를 암호화합니다.
3. UserController.수정
1. 아이디 확인 및 비밀번호 재설정 요청 처리 /resetPassword
// 아이디확인 및 비밀번호 재설정 요청을 처리하는 메서드
@PostMapping("/resetPassword")
public String handleResetPasswordRequest(@RequestParam String email, Model model) {
User user = userService.findByEmail(email);
if (user != null) {
try {
// 토큰 생성 및 사용자에 저장
String token = userService.createPasswordResetTokenForUser(user);
// 비밀번호 재설정 이메일 발송
userService.sendPasswordResetEmail(user, token);
// 비밀번호 재설정 요청이 성공적으로 처리되었다는 메시지 표시
model.addAttribute("message", "아이디찾기 및 비밀번호 재설정 이메일이 발송되었습니다.");
return "login/findIdPw"; // 비밀번호 재설정 이메일이 발송되었다는 메시지를 표시하는 뷰로 리다이렉트
} catch (MessagingException e) {
// 이메일 발송 중 오류가 발생한 경우 에러 메시지 표시
model.addAttribute("error", "비밀번호 재설정 이메일 발송 중 오류가 발생했습니다.");
return "login/findIdPw";
}
} else {
// 사용자를 찾을 수 없는 경우 에러 메시지 표시
model.addAttribute("error", "해당 이메일 주소를 가진 사용자를 찾을 수 없습니다.");
return "login/findIdPw";
}
}
사용자가 이메일 주소를 입력하면 이메일주소를 기반으로 해당사용자를 찾고 비밀번호 재설정 토큰을 생성합니다( Userservice의 createPasswordResetTokenForUser 메서드 사용)
생성된 토큰과 함께 비밀번호 재설정 링크가 포함된 이메일을 사용자에게 발송합니다. (UserService의 sendPasswordResetEmail 메소드 사용)
이메일 발송후 사용자에게 alert메시지를 표시합니다. 만약 해당하는 사용자를 찾을수 없다면 alert창을 출력후 아이디 비밀번호찾기 페이지로 return합니다.
2. 비밀번호 변경부분 처리 /changePw
//비밀번호 변경 페이지
@GetMapping("/changePw")
public String showChangePasswordPage(@RequestParam("token") String token, Model model) {
User user = userService.getUserByPasswordResetToken(token);
if (user != null) {
model.addAttribute("username", user.getUsername());
model.addAttribute("token", token);
return "login/changePw";
} else {
// 토큰이 유효하지 않거나 만료된 경우
model.addAttribute("error", "비밀번호 재설정 요청이 유효하지 않습니다.");
return "error";
}
}
// 비밀번호 변경 요청을 처리하는 메서드
@PostMapping("/changePw")
public String changeUserPassword(@RequestParam("token") String token,
@RequestParam("password") String newPassword,
Model model) {
User user = userService.getUserByPasswordResetToken(token);
if (user != null && newPassword != null) {
userService.changeUserPassword(user, newPassword);
model.addAttribute("message","비밀번호가 변경되었습니다.");
return "login/message"; // 비밀번호 변경 성공 페이지로 이동
} else {
// 토큰이 유효하지 않거나 새 비밀번호가 제공되지 않은 경우
model.addAttribute("error", "비밀번호 변경에 실패했습니다.");
return "login/changePw"; // 비밀번호 재설정 페이지로 다시 이동
}
}
사용자가 비밀번호 재설정 링크를 클릭했을때 비밀번호 변경을 위한 페이지를 표시합니다.@GetMapping("/changePw
Url에서 사용자가 비밀번호를 요청했을때 생성햇던 token 파라미터를 받고 이를 통해 사용자가 식별합니다. 유효한 토큰인 경우에는 비밀번호 변경 페이지로 이동하고 토큰이 유효하지않거나 만료된경우 오류메이지를 표시하고 아이디비밀번호 변경 페이지로 return합니다.
토큰이 유효하고 사용자가 새로운 비밀번호를 업데이트 하고(UserService의 changeUserPassword 메소드 사용) 사용자에게 alert메세지를 출력합니다. 만약 토큰이 유효하지않거나 비밀번호를 입력하지 않았을 경우 alert창을 출력합니다.
4. Html 및 css, java script 작성
아이디 비밀번호 찾기 요청페이지 findIdPW.html 작성
/reserPassword 엔드포인트로 POST요청
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org" >
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>계정정보찾기</title>
<!-- Bootstrap 4 CSS CDN -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css" />
<!-- Fontawesome CSS CDN -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" />
<link rel="stylesheet" th:href="@{css/findidpw.css}" />
</head>
<body class="bg-info full-height">
<!-- Forgot Password Form Start -->
<div class="container h-100">
<div class="row justify-content-center align-items-center h-100">
<div class="col-lg-7 bg-white p-4">
<h2 class="m-0" style="color: #D81324; padding-bottom: 40px;">
<img src="img/winelogo.jpg" alt="Image" width="50" height="50">
KOWASA <br/>
<button onclick="history.back()" class="btn btn-secondary btn-sm" style="float: right; margin-top: -50px;">
<i class="fas fa-arrow-left"></i> 뒤로가기
</button>
</h2>
<h1 class="text-center font-weight-bold text-primary" style="padding-bottom: 20px;">이메일로 계정찾기<br/></h1>
<hr class="my-3" />
<p class="lead text-center text-secondary" style="padding-bottom: 20px;">
아이디/비밀번호는 가입 등록한 메일 주소로 알려드립니다.<br/>
가입할 때 등록한 메일 주소를 입력하고 "발송" 버튼을 클릭해주세요.<br/>
</p>
<h5 style="padding-bottom: 20px;"> 가입 등록한 이메일 주소</h5>
<form th:action="@{/resetPassword}" method="post" class="px-3" id="forgot-form">
<div th:id="${forgotAlert}" th:text="${message}"></div>
<div class="input-group input-group-lg form-group">
<div class="input-group-prepend">
<span class="input-group-text rounded-0"><i class="far fa-envelope fa-lg"></i></span>
</div>
<input type="text" name="email" class="form-control rounded-0" placeholder="E-Mail" required />
</div>
<div class="form-group">
<input type="submit" id="forgot-btn" value="발송" class="btn btn-primary btn-lg btn-block myBtn" />
</div>
</form>
</div>
</div>
</div>
<!-- Forgot Password Form End -->
<!-- jQuery CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script th:src="@{js/findidpw.js}"></script>
</body>
</html>
비밀번호 변경 페이지 changePw.html 작성
/changePw 엔드포인트로 POST요청
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org" >
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>계정정보찾기</title>
<!-- Bootstrap 4 CSS CDN -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css" />
<!-- Fontawesome CSS CDN -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" />
<link rel="stylesheet" th:href="@{css/findidpw.css}" />
</head>
<body class="bg-info full-height">
<!-- Forgot Password Form Start -->
<div class="container h-100">
<div class="row justify-content-center align-items-center h-100">
<div class="col-lg-7 bg-white p-4">
<h2 class="m-0" style="color: #D81324; padding-bottom: 40px;">
<img src="img/winelogo.jpg" alt="Image" width="50" height="50">
KOWASA <br/>
</h2>
<h1 class="text-center font-weight-bold text-primary" style="padding-bottom: 20px;">비밀번호 변경<br/></h1>
<hr class="my-3" />
<form action="/changePw" method="post">
<input type="hidden" name="token" th:value="${token}"/>
<div class="input-group input-group-lg form-group">
<div class="input-group-prepend">
<span class="input-group-text rounded-0"><i class="fas fa-user"></i></span>
</div>
<input type="text" id="username" name="username" th:value="${username}" class="form-control rounded-0" placeholder="아이디" readonly/>
</div>
<div class="input-group input-group-lg form-group">
<div class="input-group-prepend">
<span class="input-group-text rounded-0"><i class="fas fa-lock"></i></span>
</div>
<input type="password" id="password" name="password" class="form-control rounded-0" placeholder="새로운 비밀번호"/>
</div>
<div class="input-group input-group-lg form-group">
<div class="input-group-prepend">
<span class="input-group-text rounded-0"><i class="fas fa-lock"></i></span>
</div>
<input type="password" id="confirmPassword" name="confirmPassword" class="form-control rounded-0" placeholder="비밀번호 재확인"/>
</div>
<div class="form-group">
<input type="submit" value="비밀번호 변경" class="btn btn-primary btn-lg btn-block myBtn" />
</div>
</form>
</div>
</div>
</div>
<!-- Forgot Password Form End -->
<!-- jQuery CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</html>
'[JAVA PROJECT]' 카테고리의 다른 글
JAVA Spring Boot 프로젝트- 5. 자유게시판 구현(페이징, 조회수) (1) | 2023.12.29 |
---|---|
JAVA Spring Boot 프로젝트- 4. 와인 검색 페이지 구현 (0) | 2023.12.28 |
JAVA Spring Boot 프로젝트-2. Oauth 2.0 구글로그인 구현하기 (0) | 2023.12.27 |
JAVA Spring Boot 프로젝트- 1. 스프링시큐리티를 이용한 회원가입 및 로그인 구현하기(2) (1) | 2023.12.23 |
JAVA Spring Boot 프로젝트- 1. 스프링 시큐리티를 이용한 회원가입 및 로그인 구현하기(1) (1) | 2023.12.21 |