프로젝트 진행하던 도중 로그인한 회원이 header에 가지고 있는 토큰을 사용해서 본인의 프로필을 비밀번호 일치 확인 후 수정하게하는 기능을 구현하게되었다.
controller
에서 스프링의 기능을 사용하여 헤더의 토큰값에 해당하는 사람의 정보를 가져와서 수정해야하는 로직으로
파라미터 값으로(@AuthenticationPrincipal UserDetailsImpl userDetails)
를 넣어주면
UserDetails
를 상속받은 UserDetailsImpl
에 있는 getUsername
을 사용할 수 있는데, 이것은 나중에 service
에서 본인확인에 사용된다.
@PutMapping("/profile")
public ResponseEntity<StatusResponse> updateUserProfile(@RequestBody UserProfileUpdateRequest userProfileUpdateRequest,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
// ...
String userInfo = userDetails.getUsername();
StatusResponse statusResponse = new StatusResponse(HttpStatus.OK.value(), "프로필 설정 완료");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(new MediaType("application", "json", StandardCharsets.UTF_8));
userService.updateUserProfile(nickname, password, userInfo);
return new ResponseEntity<>(statusResponse, headers, HttpStatus.OK);
}
그리고 service
에서
public void updateUserProfile(String nickname, String password, String userInfo) {
User user = userRepository.findByUsername(userInfo).orElseThrow(
() -> new IllegalArgumentException("해당 유저를 찾을 수 없습니다.")
);
if (user.getUsername().equals(userInfo)) {
if (passwordEncoder.matches(password, user.getPassword())) {
user.updateUserProfile(nickname);
} throw new IllegalArgumentException("비밀번호가 일치하지 않습니다.");
} throw new IllegalArgumentException("본인의 프로필만 설정할 수 있습니다.");
}
받아온 userInfo
를 레퍼지토리에서 findByUsername
하여 없다면 예외처리하고(옵셔널 타입이라 orElseThrow
를 사용하지않으면 에러가뜬다.), 2중 if문을 사용해서 레퍼지토리에 저장되어있는 username과 접근한 username을 비교하고나서 입력한 비밀번호와 Encoding된 비밀번호까지 비교한 후에 parameter로 받아온 nickname을 새로 저장한다.
오늘은 시큐리티에 일부분이지만 그래도 확실하게 알게되었는데
퇴실체크 까먹었당...ㅎ