본문 바로가기

Back-End/Spring boot

[JAVA][Spring] 본인 인증, 비밀번호 변경하기(2)

~ 목차 ~

로그인, 회원가입 기능을 만들고 난 후

로그인할 때 비밀번호가 기억이 나지 않을 때 본인인증을 통한 비밀번호 변경 기능 추가하기

1. 회원가입 기능 ------>앞의 글 참고
2. 로그인 기능    ------>앞의 글 참고

3. 본인 인증 기능

4. 비밀번호 변경 기능

 

1)UserController.java 에 추가

 

@Controller
public class UserController {
	@Autowired
	UserRepository userRepository;
    
    @Autowired
	PasswordEncoder passwordEncoder;
    
    @Autowired
	HttpSession session;

    
    // 본인 인증하기
    @PostMapping("/validateUser")
        public ResponseEntity<Map<String, Boolean>> validateUser(@RequestBody User user) {
            String email = user.getEmail();
            String name = user.getName();
            Integer phone = user.getPhone();
            List<User> resultList = userRepository.findByEmailAndNameAndPhone(email, name, phone);

            Map<String, Boolean> response = new HashMap<>();
            if (!resultList.isEmpty()) {
                response.put("isValid", true);
                // 세션에 사용자 정보 저장
                session.setAttribute("user", resultList.get(0));
            } else {
                response.put("isValid", false);
            }
            return ResponseEntity.ok(response);
        }
      
     // 비밀번호 변경하기
	@GetMapping("/pwdforget")
	public String pwdforget() {
		return "/pwdforget";
	}

	@PostMapping("/pwdforget")
	@ResponseBody
	public String pwdforgetPost(@RequestBody User user) {
		// 세션에서 사용자 정보 가져오기
    User sessionUser = (User) session.getAttribute("user");
		if (sessionUser != null) {
			String newPassword = user.getNewPassword();
			if (newPassword != null && !newPassword.isEmpty()) {
					String hashedPassword = passwordEncoder.encode(newPassword);
					sessionUser.setPwd(hashedPassword);
					userRepository.save(sessionUser);
					return "비밀번호가 성공적으로 변경되었습니다.";
			} else {
					return "비밀번호 값을 올바르게 입력하십시오.";
			}
		}
		return "비밀번호 변경에 실패하셨습니다.";
	}

}

 

2) pwdforget.html 만들기

 

<!DOCTYPE html>
<html lang="en">

<head th:replace="common/head"></head>

<body>
  <div th:replace="common/header"></div>
  <nav th:replace="common/nav"></nav>

  <div class="container mt-5">
    <div class="row">
      <form method="post" action="/pwdforget">
        <div class="mb-3">
          <label for="email">Email:</label>
          <input type="email" class="form-control" id="email" name="email" pattern="[a-z0-9._+-]+@[a-z]+\.[a-z]{2,}$"
            title=" 정확한 이메일 주소를 입력해주세요" placeholder="ex.daram@dotori.com" required>
        </div>
        <div class="mb-3">
          <label for="name">Name:</label>
          <input type="text" class="form-control" id="name" name="name" pattern="^[가-힣]+$" title="올바른 이름을 입력하세요 ex.홍길동"
            placeholder="이름" required>
        </div>
        <div class="mb-3">
          <label for="name">Phone:</label>
          <input type="text" class="form-control" id="phone" name="phone" pattern="[0-9]{10,11}"
            title="10-11자리의 숫자를 '-' 없이 입력하세요" placeholder="휴대전화번호('-'기호 제외 10~11자리)" required>
        </div>
        <div class="d-grid gap-2">
          <button type="button" class="btn btnn-primary" id="signup" onclick="validateUser()" >본인 인증하기</button>
        </div>
        <div id="change-password-form" class="d-none">
          <div class="mb-3">
            <label for="pwd">New Password:</label>
            <input type="password" class="form-control" id="newPassword" name="newPassword"
              pattern="(?=.*\d)(?=.*[a-zA-Z]).{8,}" title="영문대소문자/숫자로 이루어진 최소 8글자의 비밀번호를 입력하세요"
              placeholder="새로운 비밀번호를 입력하세요">
            <i class="fa fa-eye fa-lg eyes" th:attr="onclick='togglePasswordVisibility()'"></i>
          </div>
          <div class="d-grid gap-2">
            <button type="button" class="btn btnn-primary" id="changePassword">비밀번호
              변경</button>
          </div>
        </div>

        <div id="error-message1" class="d-none" style="color: red; margin: 10px;">
          <p>입력하신 정보와 일치하는 사용자를 찾을 수 없습니다.</p>
        </div>
      </form>

    </div>
  </div>
  <script>
    //본인 인증
    function validateUser() {
      var email = document.getElementById('email').value;
      var name = document.getElementById('name').value;
      var phone = document.getElementById('phone').value;

      // AJAX 요청을 사용하여 서버에 사용자의 정보가 유효한지 확인합니다.
      $.ajax({
        url: '/validateUser',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
          email: email,
          name: name,
          phone: phone
        }),
        success: function (response) {
          if (response.isValid) {
            // 유효하면 비밀번호 변경 폼을 보여줍니다.
            document.getElementById('error-message1').classList.add('d-none');
            document.getElementById('change-password-form').classList.remove('d-none');
          } else {
            // 유효하지 않으면 에러 메시지를 보여줍니다.
            document.getElementById('error-message1').classList.remove('d-none');
          }
        }
      });
    }

    //비밀번호 변경
    const changeBtn = document.querySelector('#changePassword')
    changeBtn.addEventListener('click', changePassword);
    function changePassword() {
      var email = document.getElementById('email').value;
      var name = document.getElementById('name').value;
      var phone = document.getElementById('phone').value;
      var newPassword = document.getElementById('newPassword').value;
      console.log(newPassword);

      //data 속성을 통해 내용을 서버로 전달
      $.ajax({
        url: '/pwdforget',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
          email: email,
          name: name,
          phone: phone,
          newPassword: newPassword
        }),
        success: function (response) {
          // 서버에서 응답이 오면, 성공 메시지를 보여줍니다.
          alert(response);
          location = '/signin';
        },
        error: function (error) {
          // 에러가 발생한 경우, 에러 메시지를 보여줍니다.
          alert("오류가 발생했습니다: " + error.responseText);
        }
      });
    }
    

    // 비밀번호 보이기표시
    function togglePasswordVisibility() {
      var $passwordInput = $('#newPassword'); // ID를 사용하여 비밀번호 입력란을 선택
      if ($passwordInput.attr('type') === 'password') {
        $('.eyes').removeClass('fa-eye').addClass('fa-eye-slash');
        $passwordInput.attr('type', 'text');
      } else {
        $('.eyes').removeClass('fa-eye-slash').addClass('fa-eye');
        $passwordInput.attr('type', 'password');
      }
    }

  </script>
  </div>

  <div th:replace="common/footer" style="margin-top: 1rem;">
  </div>

</body>

</html>

 

※ 본인인증은 user 데이터베이스에 있는 email, name 그리고 phone 번호가 일치하면 비밀번호 변경 창이 나타나게 설정하였다.

※ 비밀번호 변경은 새로 입력한 비밀번호가 서버로 전달되고 서버에서 다시 암호화 시켜서 user의 pwd에 다시 저장시도록 하였다.

※ 처음에는 새로 입력한 비밀번호를 세션에 넣지 않았더니 내가 본인 인증 후에 새로 입력한 비밀번호가  /pwdforget에 넘어가지 않아서 오류가 뜨는 걸 발견하고 본인인증과 비밀번호 변경을 따로 javascript해서 그런 것을 알았다 두 js를 연결하기 위해 newPassword 정보를 session에 저장하는 방법으로 해결하였다.

※ javascript에 ajax를 사용하면 ajax가 form 역할을 하므로 form안에 button을 type="button" 으로 해야지 type="submit"으로 하면 주소는 그대로인데 새로운 창으로 나타나게 되므로 조심해야하는 것을 알았다.

그리고 아래 코드가 

 

$.ajax({
        url: '/validateUser',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
          email: email,
          name: name,
          phone: phone
        })
 

 

AJAX 요청을 사용하여 서버와 통신 하여 내용을 서버로 전달 할 수 있는 것을 알았다. (form기능 대체)

 


결과물

 

본인인증 결과(잘못된 정보 넣었을때)
본인인증 후 비밀번호 변경 입력 창
비밀번호 변경 성공!

 

728x90