최근에 스프링시큐리티 책을 보다가 SLiPP는 어떻게 했는가싶어, Github에서 SLiPP 프로젝트에 '*비밀번호 변경*'기능 흐름(컨트롤러->서비스->도메인객체) 보던중 서비스 클래스에 변경한 비밀번호를 DB에 update하는 부분이 없어 질문드립니다.
SocialUserService.java, SocialUser.java 파일들의 changePassword메소드에 새로 변경할려는 비밀번호를 DB에 update하는 부분이 없는것은 보안때문인가요? ^^ 아님 다른곳에서 그 부분을 처리하는지 궁금합니다 ^^
src / main / java / net / slipp / web / user / UsersController.java
@RequestMapping(value = "{id}/changepassword", method = RequestMethod.POST)
public String changePassword(@LoginUser SocialUser loginUser, @PathVariable Long id, PasswordDto password, Model model) throws Exception {
SocialUser socialUser = userService.findById(id);
if (!loginUser.isSameUser(socialUser)) {
throw new IllegalArgumentException("You cann't change another user!");
}
try {
userService.changePassword(loginUser, password);
return "redirect:/users/logout";
} catch (BadCredentialsException e) {
model.addAttribute("errorMessage", e.getMessage());
model.addAttribute("socialUser", socialUser);
model.addAttribute("password", new PasswordDto(id));
return "users/changepassword";
}
}
src/main/java/net/slipp/service/user/SocialUserService.java
src/main/java/net/slipp/service/user/SocialUserService.java
public SocialUser changePassword(SocialUser loginUser, PasswordDto password) {
SocialUser user = socialUserRepository.findOne(password.getId());
if (user == null) {
return null;
}
user.changePassword(passwordEncoder, password.getOldPassword(), password.getNewPassword());
return user;
}
src/main/java/net/slipp/domain/user/SocialUser.java
public void changePassword(PasswordEncoder encoder, String oldPassword, String newPassword) {
String oldEncodedPassword = encoder.encodePassword(oldPassword, null);
if (!password.equals(oldEncodedPassword)) {
throw new BadCredentialsException("현재 비밀번호가 다릅니다.");
}
this.password = encoder.encodePassword(newPassword, null);
}
2개의 의견 from SLiPP
이 부분을 이해하려면 ORM에 대해서 이해해야 되는데요. 지금 slipp은 JPA 기반으로 개발되어 있는데요. SocialUserService의 changePassword를 실행하는 순간 transaction이 시작됩니다. 이 때 데이터베이스에서 사용자 정보를 조회한 후 비밀번호를 변경합니다. 이 변경된 비밀번호 정보는 SocialUserService의 changePassword가 끝나는 시점에 transaction이 종료되면서 데이터의 상태가 변경되었는지를 파악해 ORM이 자동적으로 데이터베이스에 상태를 반영해 줍니다. 따라서 특별히 Repository를 활용해 데이터베이스에 반영해 주지 않아도 데이터가 변경되는 방식입니다.
위 예제는 복잡하니 spring의 transaction과 JPA(또는 Hibernate 만으로도 가능) 연동해서 테스트 예제 한번 만들고 공부해 보심 확인하실 수 있을 겁니다.
@자바지기 허접한 질문에 답변을 해주셔서 감사합니다. ^^ 하이버네이트에 대한 이해가 있어야했었군요.
의견을 남기기 위해서는 SLiPP 계정이 필요합니다.
안심하세요! 회원가입/로그인 후에도 작성하시던 내용은 안전하게 보존됩니다.
SLiPP 계정으로 로그인하세요.
또는, SNS 계정으로 로그인하세요.