로그인 실패시 사용자에게 잘못된 로그인 정보임을 알려주고 다시 로그인하도록 한다.
MemberController 수정
@PostMapping("/member/login")
public String login(Member member, HttpSession session, Model model) {
Optional<Member> optionalLoginUser = memberService.selectMemberByUsername(member);
if (optionalLoginUser.isPresent()) {
Member loginUser = optionalLoginUser.get();
if (pEncoder.matches(member.getPassword(), loginUser.getPassword())) {
session.setAttribute("loginUser", loginUser);
return "redirect:/";
}else {
model.addAttribute("loginError", "로그인 정보가 올바르지 않습니다.");
return "member/login";
}
}
model.addAttribute("loginError", "로그인 정보가 올바르지 않습니다.");
return "member/login";
}
login.jsp 버튼 부분 위에 에러 문구 띄워줄 공간을 만들어준다.
<tr>
<td colspan="2">
<c:if test="${not empty loginError}">
<div class="error-text">${loginError}</div>
</c:if>
</td>
</tr>
아이디 찾기 기능 구현 : 아이디를 찾을 때는 사용자의 이름과 전화번호를 이용해 일치하는 ID 값을 찾도록 구현하였다.
<section>
<div class="findId">
<h3>아이디 찾기</h3>
<form action="findId" method="post" id="findIdForm">
<table>
<tr>
<th><label for="name">NAME</label></th>
<td>
<div>
<input name="name" id="name" class="form-control" placeholder="이름" type="text">
</div>
</td>
</tr>
<tr>
<th><label for="phoneNumber">PHONE</label></th>
<td>
<input name="phoneNumber" id="phoneNumber" class="form-control" placeholder="전화번호" type="text" maxlength="11">
</td>
</tr>
<tr>
<td colspan="2">
<button type="submit">아이디 찾기</button>
</td>
</tr>
</table>
</form>
<div id="findIdResult"></div>
</div>
</section>
@GetMapping("member/findId")
public String findId() {
return "member/findId";
}
아이디를 찾기 기능도 AJAX로 구현한다.
$(() => {
$("#findIdForm").on('submit', function(e) {
e.preventDefault();
const name = $("#name").val();
const phoneNumber = $("#phoneNumber").val();
if (!name || !phoneNumber) {
$("#findIdResult").html("모든 필드를 입력해주세요.");
return;
}
$.ajax({
url: "findId",
type: "post",
data : {
name: name,
phoneNumber: phoneNumber
},
success: function (result) {
console.log(result);
if(result) {
$("#findIdResult").html("찾으시는 아이디는 `" + result.username + "` 입니다.");
$("#findIdResult").append('<div><a href="/member/login">[로그인으로 돌아가기]</a></div>');
} else {
$("#findIdResult").html("아이디를 찾을 수 없습니다.");
}
},
error: function() {
console.log("아이디 찾기 ajax 통신 실패");
}
});
})
});
</script>
controller
@PostMapping("member/findId")
@ResponseBody
public Member findUserID(@RequestParam("name") String name, @RequestParam("phoneNumber") String phoneNumber) {
Member findId = memberService.findIdByNameAndPhoneNumber(name, phoneNumber);
System.out.println("Found Member: " + findId);
return findId;
}
service
public Member findIdByNameAndPhoneNumber(String name, String phoneNumber) {
Member findId = memberRepository.findByNameAndPhoneNumber(name, phoneNumber);
return findId;
}
repository
@Query("SELECT m FROM Member m WHERE m.name = :name AND m.phoneNumber = :phoneNumber")
Member findByNameAndPhoneNumber(@Param("name") String name, @Param("phoneNumber") String phoneNumber);
비밀번호 재설정 기능 구현 : 요즘에는 비밀번호를 잊어버렸을 경우 찾기가 아니라 재설정하도록 한다. 재설정하는 경우 계정 확인을 다시 한 번 하도록 한다. 계정 확인은 사용자의 아이디와 이름, 전화번호를 통해 확인하고 계정이 확인된 경우 비밀번호를 재설정할 수 있도록하였다.
<section>
<div class="resetPw">
<h3>비밀번호 재설정</h3>
<form action="checkForResetPw" method="post" id="checkForResetPwForm">
<table>
<tr>
<th><label for="username">ID</label></th>
<td>
<div>
<input name="username" id="username" class="form-control" placeholder="아이디" type="text">
</div>
</td>
</tr>
<tr>
<th><label for="name">NAME</label></th>
<td>
<div>
<input name="name" id="name" class="form-control" placeholder="이름" type="text">
</div>
</td>
</tr>
<tr>
<th><label for="phoneNumber">PHONE</label></th>
<td>
<input name="phoneNumber" id="phoneNumber" class="form-control" placeholder="전화번호" type="text" maxlength="11">
</td>
</tr>
<tr>
<td colspan="2">
<button type="submit">계정 확인</button>
</td>
</tr>
</table>
</form>
<div id="findIdResult"></div>
<form action="resetPw" method="post" id="resetPwForm" style="display:none;">
<table>
<tr>
<th><label for="password">PW</label></th>
<td>
<div>
<input type="password" name="password" id="password" placeholder="영문, 숫자, 영문자 포함 8~12글자" maxlength="12">
<div id="checkPwResult1" style="font-size: 0.8em; display: none;"></div>
</div>
</td>
</tr>
<tr>
<th><label for="password">PW 확인</label></th>
<td>
<div>
<input type="password" id="passwordCheck" placeholder="비밀번호를 한번 더 입력해주세요." maxlength="12">
<div id="checkPwResult2" style="font-size: 0.8em; display: none;"></div>
</div>
</td>
</tr>
<tr>
<td colspan="2">
<!-- hidden 필드 추가 -->
<input type="hidden" name="memberId" id="hiddenMemberId">
<input type="hidden" name="username" id="hiddenUsername">
<input type="hidden" name="name" id="hiddenName">
<input type="hidden" name="email" id="hiddenEmail">
<input type="hidden" name="phoneNumber" id="hiddenPhoneNumber">
<input type="hidden" name="homeAddress" id="hiddenHomeAddress">
</td>
</tr>
<tr>
<td colspan="2">
<button type="submit">비밀번호 재설정</button>
</td>
</tr>
</table>
</form>
</div>
</section>
비밀번호 재설정 폼은 재설정 하기 전에 계정 확인을 먼저 해야하므로 처음 페이지에 들어오면 계정확인하는 폼을 먼저
보이게 하고 계정 확인이 완료되면 비밀번호를 재설정하는 폼이 뜬다.
@GetMapping("member/resetPw")
public String resetPw() {
return "member/resetPw";
}
계정 확인이 안되면, 비밀번호 재설정 창이 뜨지 않는다.
계정 확인이 되면 재설정 창이 뜬다.
<script>
$(() => {
$("#checkForResetPwForm").on('submit', function(e) {
e.preventDefault();
const username = $("#username").val();
const name = $("#name").val();
const phoneNumber = $("#phoneNumber").val();
// 입력값 검증
if (!username || !name || !phoneNumber) {
$("#findIdResult").html("모든 필드를 입력해주세요.");
$("#resetPwForm").hide();
return;
}
$.ajax({
url: "checkForResetPw",
type: "post",
data : {
username: username,
name: name,
phoneNumber: phoneNumber
},
success: function (result) {
if(result && result.username === username) {
$("#findIdResult").html("계정확인이 되었습니다.");
$("#hiddenMemberId").val(result.memberId);
$("#hiddenUsername").val(result.username);
$("#hiddenName").val(result.name);
$("#hiddenEmail").val(result.email);
$("#hiddenPhoneNumber").val(result.phoneNumber);
$("#hiddenHomeAddress").val(result.homeAddress);
$("#resetPwForm").show();
} else {
$("#findIdResult").html("계정을 찾을 수 없습니다.");
$("#resetPwForm").hide();
}
},
error: function() {
console.log("계정 확인 ajax 통신 실패");
$("#resetPwForm").hide();
}
});
});
});
비밀번호를 재설정을 하면 재설정한 비밀번호에 대해서 회원가입시에 했던 것과 마찬가지로 같은 조건으로 유효성 검사를 해준다.
비밀번호 유효성 검사
$(() => {
const $pwInput = $("#password");
var getPwCheck = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@#$!%])[A-Za-z\d@#$!%]{8,12}$/;
const $checkPwResult1 = $("#checkPwResult1");
const $enrollFormSubmit = $("#resetPwForm :submit");
$pwInput.on('input', function() {
const pw = $pwInput.val();
if(!pw) {
$checkPwResult1.show().css("color", "red").text('비밀번호를 입력해주세요.');
$enrollFormSubmit.attr("disabled", true);
return;
} else if (!getPwCheck.test(pw)) {
$checkPwResult1.show().css("color", "red").text('비밀번호는 영문과 숫자, 특수기호를 포함해 8~12자 입니다.');
$enrollFormSubmit.attr("disabled", true);
return;
} else {
$checkPwResult1.show().css("color", "green").text('유효한 비밀번호입니다.');
$enrollFormSubmit.attr("disabled", false);
}
})
});
비밀번호 입력, 비밀번호 확인 두 정보가 일치하는지를 확인한다.
$(function() {
const $password = $("#password");
const $passwordCheck = $("#passwordCheck");
const $checkPwResult2 = $("#checkPwResult2");
const $resetPwFormSubmit = $("#resetPwForm :submit");
function validatePassword() {
const pw = $password.val();
const pwCheck = $passwordCheck.val();
if (pw !== pwCheck) {
$checkPwResult2.show().css("color", "red").text('비밀번호가 불일치합니다. 다시 입력해주세요.');
$resetPwFormSubmit.attr("disabled", true);
} else {
$checkPwResult2.show().css("color", "green").text('비밀번호가 일치합니다.');
$resetPwFormSubmit.attr("disabled", false);
}
}
$password.on('input', validatePassword);
$passwordCheck.on('input', validatePassword);
});
</script>
controller
@PostMapping("member/checkForResetPw")
@ResponseBody
public Member checkForResetPw(@RequestParam("username") String username,
@RequestParam("name") String name,
@RequestParam("phoneNumber") String phoneNumber) {
Member findMemberForPw = memberService.findIdByUserNameAndNameAndPhoneNumber(username,name, phoneNumber);
System.out.println("Found Member: " + findMemberForPw);
return findMemberForPw;
}
service
public Member findIdByUserNameAndNameAndPhoneNumber(String username, String name, String phoneNumber) {
Member findMemberForRestPw = memberRepository.findByUserNameAndNameAndPhoneNumber(username, name, phoneNumber);
return findMemberForRestPw;
}
repository
@Query("SELECT m FROM Member m WHERE m.username = :username AND m.name = :name AND m.phoneNumber = :phoneNumber")
Member findByUserNameAndNameAndPhoneNumber(String username, String name, String phoneNumber);
처음에 ID와 PW를 찾아올 때 string으로 username(ID) 만 찾도록 했다.그런데 이렇게 하면 비밀번호를 재설정하고 다시 저장을 하면 아래와 같이 비밀번호만 들어가고 다른 부분은 다 null로 새로 저장이 되는 문제가 있었다.
따라서 객체를 받아와 다른 필드도 사용할 수 있도록 처리해줬다.
이렇게 비밀번호를 제외한 필드들은 hidden으로 추가해준다.
ajax 요청이 성공하면 계정 확인된 객체의 값을 불러와 히든 처리해준 곳에 값을 넣어준다.
그러면 정상적으로 비밀번호만 업데이트되고 나머지 값들은 그대로 저장이 된다.
'프로젝트' 카테고리의 다른 글
영화 예매 사이트 (MoVieCinema) - 마이페이지 화면 AJAX로 띄우기 (0) | 2024.04.13 |
---|---|
영화 예매 사이트 (MoVieCinema) - 리뷰에 별점 항목 추가 (0) | 2024.04.13 |
영화 예매 사이트 (MoVieCinema) - 마이페이지 정보 수정 (0) | 2024.04.13 |
영화 예매 사이트 (MoVieCinema) - 회원 가입 유효성 검사 (0) | 2024.04.13 |
영화 예매 사이트 (MoVieCinema) - 영화 검색 (0) | 2024.04.13 |