패스워드 변경
- 패스워드 탭 활성화
- 새 패스워드와 새 패스워드 확인의 값이 일치해야 한다.
- 패스워드 인코딩 할 것!
- 둘 다 최소 8자에서 최대 50자 사이.
- 사용자 정보를 변경하는 작업.
- 서비스로 위임해서 트랜잭션 안에서 처리해야 한다.
- 또는 Detached 상태의 객체를 변경한 다음 Repository의 save를 호출해서 상태 변경 내역을 적용 할 것(Merge)
새로운 패스워드를 입력받기위한 PasswordForm DTO를 생성
package me.weekbelt.studyolle.settings;
@NoArgsConstructor
@Data
public class PasswordForm {
@Length(min = 8, max = 50)
private String newPassword;
@Length(min = 8, max = 50)
private String newPasswordConfirm;
}
패스워드와 패스워드 확인이 같은지 체크하기위해 Validator생성
package me.weekbelt.studyolle.settings;
public class PasswordFormValidator implements Validator {
@Override
public boolean supports(Class<?> aClass) {
return PasswordForm.class.isAssignableFrom(aClass);
}
@Override
public void validate(Object target, Errors errors) {
PasswordForm passwordForm = (PasswordForm) target;
if (!passwordForm.getNewPassword().equals(passwordForm.getNewPasswordConfirm())) {
errors.rejectValue("newPassword", "wrong.value", "입력한 새 패스워드가 일치하지 않습니다.");
}
}
}
SettingsController에 Validator등록
package me.weekbelt.studyolle.settings;
@RequiredArgsConstructor
@Controller
public class SettingsController {
@InitBinder("passwordForm")
public void initBinder(WebDataBinder webDataBinder) {
webDataBinder.addValidators(new PasswordFormValidator());
}
// 기존 코드 .........
}
패스워드 수정 폼의 GET 요청과 수정의 POST요청 구현
package me.weekbelt.studyolle.settings;
@RequiredArgsConstructor
@Controller
public class SettingsController {
// 기존 코드 .....
@GetMapping("/settings/password")
public String updatePasswordForm(@CurrentUser Account account, Model model) {
model.addAttribute(account);
model.addAttribute(new PasswordForm());
return "settings/password";
}
@PostMapping("/settings/password")
public String updatePassword(@CurrentUser Account account,
@Valid PasswordForm passwordForm,
Errors errors, Model model,
RedirectAttributes attributes) {
if (errors.hasErrors()) {
model.addAttribute(account);
return "settings/password";
}
accountService.updatePassword(account, passwordForm.getNewPassword());
attributes.addFlashAttribute("message", "패스워드를 변경했습니다.");
return "redriect:" + "/settings/password";
}
}
SettingsService에서 패스워드 수정을 처리하기위해 updatePassword메소드 구현
package me.weekbelt.studyolle.account;
@Transactional
@RequiredArgsConstructor
@Service
public class AccountService implements UserDetailsService {
// 기존 코드 ........
public void updatePassword(Account account, String newPassword) {
account.setPassword(passwordEncoder.encode(newPassword));
accountRepository.save(account); // merge
}
}
패스워드 수정 폼인 /settings/password.html 작성
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<!--head-->
<head th:replace="fragments.html::head"></head>
<body class="bg-light">
<!--네비게이션 바-->
<div th:replace="fragments.html::main-nav"></div>
<div class="container">
<div class="row mt-5 justify-content-center">
<div class="col-2">
<div th:replace="fragments.html :: settings-menu(currentMenu='password')"></div>
</div>
<div class="col-8">
<div th:if="${message}" class="alert alert-info alert-dismissible fade show mt-3" role="alert">
<span th:text="${message}">메시지</span>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">x</span>
</button>
</div>
<div class="row">
<h2 class="col-sm-12">패스워드 변경</h2>
</div>
<div class="row mt-3">
<form class="needs-validation col-12" action="#"
th:action="@{/settings/password}" th:object="${passwordForm}" method="post" novalidate>
<div class="form-group">
<label for="newPassword">새 패스워드</label>
<input id="newPassword" type="password" th:field="*{newPassword}" class="form-control"
aria-describedby="newPasswordHelp" required min="8" max="50">
<small id="newPasswordHelp" class="form-text text-muted">
새 패스워드를 입력하세요.
</small>
<small class="invalid-feedback">패스워드를 입력하세요.</small>
<small class="form-text text-danger" th:if="${#fields.hasErrors('newPassword')}" th:errors="*{newPassword}">
New Password Error
</small>
</div>
<div class="form-group">
<label for="newPasswordConfirm">새 패스워드 확인</label>
<input id="newPasswordConfirm" type="password" th:field="*{newPasswordConfirm}" class="form-control"
aria-describedby="newPasswordConfirmHelp" required min="8" max="50">
<small id="newPasswordConfirmHelp" class="form-text text-muted">
새 패스워드를 다시 한번 입력하세요.
</small>
<small class="invalid-feedback">새 패스워드를 다시 입력하세요.</small>
<small class="form-text text-danger" th:if="${#fields.hasErrors('newPasswordConfirm')}" th:errors="*{newPasswordConfirm}">
New Password Error
</small>
</div>
<div class="form-group">
<button class="btn btn-outline-primary" type="submit" aria-describedby="submitHelp">패스워드 변경하기기
</button>
</div>
</form>
</div>
</div>
</div>
<!-- footer -->
<div th:replace="fragments.html::footer"></div>
</div>
<script th:replace="fragments.html::form-validation"></script>
</body>
</html>
참고: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-JPA-%EC%9B%B9%EC%95%B1#
'스프링과 JPA 기반 웹 어플리케이션 개발 > 1부 (개발환경, 회원가입, 로그인, 계정설정)' 카테고리의 다른 글
28. 알림 설정 (0) | 2020.04.22 |
---|---|
27. 패스워드 수정 테스트 (0) | 2020.04.22 |
25. 프로필 이미지 변경 (0) | 2020.04.21 |
24. 프로필 수정 테스트 (0) | 2020.04.21 |
23. 프로필 수정 처리 (0) | 2020.04.21 |