spring boot 게시판 - 7 <회원 정보 수정 및 탈퇴>

2022. 11. 24. 22:13·Java/Spring Boot 게시판
목차
  1. ✅ 회원 정보 수정 <이름 변경>
  2. ✅ 회원 정보 수정 <비밀번호 변경>
  3. ✅ 회원 탈퇴
  4. ✅ 끝
728x90

2022.11.22 - [Java/spring 게시판] - spring boot 게시판 - 6

 

spring boot 게시판 - 6 <bootstrap 적용하기>

https://magicmk.tistory.com/32 spring boot 게시판 - 5 https://magicmk.tistory.com/31 spring boot 게시판 - 4 https://magicmk.tistory.com/29 spring boot 게시판 - 3 https://magicmk.tistory.com/28 spring boot 게시판 - 2 https://magicmk.tistory.com/

magicmk.tistory.com

이전 시간에 머리 식히려고 프론트 관련된 내용을 진행했었는데 이번에는 회원 정보 수정 및 탈퇴를 구현했다.


✅ 회원 정보 수정 <이름 변경>

현재 member entity에 email은 pk로 지정되어 있고 나머지 컬럼은 username과 password 밖에 없어서

둘 다 한번에 수정을 할까 하다가 그냥 하나씩 수정할 수 있도록 구현했다.

 

⏹️ MemberController.java

/**
 * 회원 이름 변경
 * @param model
 * @param authentication 인증 정보
 * @return 회원 이름 변경 페이지
 */
@GetMapping("/update/username")
public String updateUsernameForm(Model model, Authentication authentication) {
    UserDetails userDetails = (UserDetails) authentication.getPrincipal();
    MemberResponseDTO member = memberService.findMember(userDetails.getUsername());
    model.addAttribute("member", member);

    return "/members/updateUsername";
}

우선 회원 정보 수정 페이지에 접근할 때 Authentication을 통해 유저 정보를 확인하고

최대한 view 영역에서 Entity를 알 수 없도록 지정된 DTO를 반환하였다.

 

⏹️ 회원 정보 수정 화면

회원 정보 수정 페이지

DTO를 반환 받아서 Email과 User name을 보여주고 email은 pk라 변경할 수 없으니 readonly를 걸어주고

username만 변경할 수 있도록 해뒀다.

 

⏹️ MemberController.java

/**
 * 회원 이름 변경 post
 * @param memberUsernameUpdateDTO
 * @param errors
 * @param model
 * @return 회원 정보 페이지
 */
@PostMapping("/update/username")
public String updateUsername(@Valid MemberUsernameUpdateDTO memberUsernameUpdateDTO, Errors errors, Model model, Authentication authentication) {
    if (errors.hasErrors()) {
        model.addAttribute("member", memberUsernameUpdateDTO);
        globalService.messageHandling(errors, model);
        return "/members/updateUsername";
    }

    memberService.updateMemberUsername(memberUsernameUpdateDTO);

    return "redirect:/member/info";
}

다시 컨트롤러로 넘어와서 이번에는 username을 변경한 뒤 update를 클릭하면 작동할 로직을 구현했다.

 

username의 유효성 검사를 진행해야 하니 검증 코드를 거쳐 유효성 검사를 진행하고

검증이 완료 됐다면 service에 정보를 넘겨준다.

 

그전에 먼저 Member Entity에서 메서드를 작성해준다.

 

⏹️ Member.java

public void updateUsername(String username) {
    this.username = username;
}

public void updatePassword(String password) {
    this.password = password;
}

repository를 제외한 다른 영역에서 Entity를 수정할 수 있게 만들고 싶지 않아서 최대한 이런 메서드는

쓰지 않으려고 했지만 별다른 방안을 찾지 못해서 결국 메서드를 만들었다.

(혹시 다른 방법을 알고 계신분은 알려주시면 감사하겠습니다. 꾸벅)

 

⏹️ MemberServiceImpl.java

@Override
public Long updateMemberUsername(MemberUsernameUpdateDTO memberUsernameUpdateDTO) {
    Member member = memberRepository.findByEmail(memberUsernameUpdateDTO.getEmail()).orElseThrow(() -> new UsernameNotFoundException("이메일이 존재하지 않습니다."));

    member.updateUsername(memberUsernameUpdateDTO.getUsername());
    memberRepository.save(member);

    return member.getId();
}

Member Entity에 메서드를 만들었다면 Service 영역에서 넘겨받은 데이터를 통해 유저를 찾고

해당 유저의 username을 변경한 뒤 다시 save 해주고 id를 리턴한다.

저 리턴 값은 지금은 무의미 하지만 프로젝트가 커지면 사용할 수 있으니 저렇게 만들어 놓았다.

 

⏹️ 회원 정보 수정 테스트

변경 전

변경 전을 보면 User name이 minki로 나타난다.

변경 중

User name을 magic으로 변경해 보았다.

변경 완료

성공적으로 User name이 변경되었다.


✅ 회원 정보 수정 <비밀번호 변경>

비밀번호 변경은 현재 비밀번호를 입력하고 변경할 비밀번호를 두 번 입력하는 형식으로 작성하였다.

하지만 현재 비밀번호가 맞지 않았을 경우 Exception이 터지는 것을 좀 더 간결하고 멋지게

작성하고 싶었는데 구닥다리(?) 식으로 구현한 것 같아서 마음에 들지 않는다..

 

⏹️ 비밀번호 변경 화면

비밀번호 변경 화면

비밀번호 변경 url로 접속하면 별다른 내용 없이 해당 화면이 표시되게 만들었다.

 

⏹️ MemberController.java

/**
 * 회원 비밀번호 변경 post
 * @param memberPasswordUpdateDTO
 * @param model
 * @param authentication
 * @return 회원 정보 페이지
 */
@PostMapping("/update/password")
public String updatePassword(@Valid MemberPasswordUpdateDTO memberPasswordUpdateDTO, Model model, Authentication authentication) {
    // new password 비교
    if (!Objects.equals(memberPasswordUpdateDTO.getNewPassword(), memberPasswordUpdateDTO.getConfirmPassword())) {
        model.addAttribute("dto", memberPasswordUpdateDTO);
        model.addAttribute("differentPassword", "비밀번호가 같지 않습니다.");
        return "/members/updatePassword";
    }

    UserDetails userDetails = (UserDetails) authentication.getPrincipal();
    Long result = memberService.updateMemberPassword(memberPasswordUpdateDTO, userDetails.getUsername());

    // 현재 비밀번호가 틀렸을 경우
    if (result == null) {
        model.addAttribute("dto", memberPasswordUpdateDTO);
        model.addAttribute("wrongPassword", "비밀번호가 맞지 않습니다.");
        return "/members/updatePassword";
    }

    return "redirect:/member/info";
}

코드가 굉장히 난잡하다...

우선 첫번째 분기문을 보면 DTO을 통해 현재 비밀번호, 새 비밀번호, 확인 비밀번호 이렇게 3가지를 전달받는데

새 비밀번호와 확인 비밀번호가 같은지를 확인하고 다르다면 입력했던 정보들과 함께 메세지를 보낸다.

 

확인 비밀번호 오류

비밀번호 2개가 다르면 위와 같은 메세지가 나온다.

 

그리고 Authentication을 통해 User 정보를 받아온 뒤 Service 영역으로 해당 정보와 비밀번호 정보를 함께 넘겨준다.

그런 뒤 결괏값이 있다면 변경이 완료되어 유저 프로필 페이지로 넘어가고

결과값이 없다면 입력했던 비밀번호 정보와 함께 기존 비밀번호가 틀렸다는 메세지를 넘겨준다.

 

기존 비밀번호 오류

위와 같이 기존 비밀번호가 맞지 않다는 오류를 출력한다.

 

⏹️ MemberServiceImpl.java

@Override
public Long updateMemberPassword(MemberPasswordUpdateDTO memberPasswordUpdateDTO, String email) {
    Member member = memberRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException("이메일이 존재하지 않습니다."));

    if (!passwordEncoder.matches(memberPasswordUpdateDTO.getCurrentPassword(), member.getPassword())) {
        return null;
    } else {
        memberPasswordUpdateDTO.setNewPassword(passwordEncoder.encode(memberPasswordUpdateDTO.getNewPassword()));
        member.updatePassword(memberPasswordUpdateDTO.getNewPassword());
        memberRepository.save(member);
    }

    return member.getId();
}

Service 영역에서는 전달받은 데이터를 가지고 member 객체를 가져오고

해당 member의 비밀번호와 전달 받은 기존 비밀번호가 같은지를 체크한다.

 

같지 않다면 null을 리턴하고 같다면

새로운 비밀번호를 암호화해서 비밀번호를 update하고 save를 진행한다.

 

⏹️ 비밀번호 변경 테스트

기존 비밀번호
변경된 비밀번호

비밀번호가 제대로 변경되었다.


✅ 회원 탈퇴

회원 탈퇴는 그냥 버튼만 누르면 할 수 있도록 만들까 하다가 그래도 비밀번호로 한 번쯤은 체크하자 싶어서

아래처럼 구성하였다.

 

⏹️ 회원 탈퇴 화면

회원 탈퇴 화면

위처럼 회원 탈퇴 페이지로 들어가면 비밀번호를 입력한 뒤 탈퇴를 할 수 있도록 만들었다.

 

⏹️ MemberController.java

/**
 * 회원 탈퇴 post
 * @param password
 * @param model
 * @param authentication
 * @return 홈 페이지
 */
@PostMapping("/withdrawal")
public String memberWithdrawal(@RequestParam String password, Model model, Authentication authentication) {
    UserDetails userDetails = (UserDetails) authentication.getPrincipal();
    boolean result = memberService.withdrawal(userDetails.getUsername(), password);

    if (result) {
        return "redirect:/logout";
    } else {
        model.addAttribute("wrongPassword", "비밀번호가 맞지 않습니다.");
        return "/members/withdrawal";
    }
}

여기서는 비밀번호를 하나만 입력받기 때문에 DTO를 통해 받지 않고 @RequestParam을 통해 직접 받았다.

 

Service영역으로 데이터를 전달하면 boolean값을 리턴하는데 회원 탈퇴가 완료되면 true를 리턴한다.

회원 탈퇴가 이루어진 뒤 로그아웃이 진행되지 않아 리턴 값을 logout으로 리다이렉트 시켰다.

 

그리고 여기서도 비밀번호가 맞는지를 확인하는데 이 부분은 위에서 설명했으니 패스

 

⏹️ MemberServiceImpl.java

@Override
public boolean withdrawal(String email, String password) {
    Member member = memberRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException("이메일이 존재하지 않습니다."));

    if (passwordEncoder.matches(password, member.getPassword())) {
        memberRepository.delete(member);
        return true;
    } else {
        return false;
    }
}

전달받은 데이터로 member 객체를 가져온 뒤 비밀번호를 검사하고 맞다면 회원을 삭제한 뒤 true값을 리턴하고

아니면 false를 리턴한다.


✅ 끝

아무리 봐도 코드에 분기문이 너무 많아 마음에 들지 않지만 일단 어떻게든 작동되게 만들었다..

엄청 쉬운 작업인데도 혼자 하려니 만만치 않은 것 같다.

이래서 개발은 이것저것 만들어 봐야 한다고 하는 것 같다. 다음에는 본격적으로 게시글에 관련된

로직을 구현해보겠다.

 

https://github.com/Kimmingki/board

 

GitHub - Kimmingki/board: 강의만 듣다 때려치우지 말고 조금씩이라도 개발해보자...!!

강의만 듣다 때려치우지 말고 조금씩이라도 개발해보자...!! Contribute to Kimmingki/board development by creating an account on GitHub.

github.com

저작자표시 비영리 (새창열림)

'Java > Spring Boot 게시판' 카테고리의 다른 글

spring boot 게시판 - 9 <게시물 수정, 삭제>  (2) 2022.11.30
spring boot 게시판 - 8 <게시물 작성, 조회>  (0) 2022.11.30
spring boot 게시판 - 6 <bootstrap 적용하기>  (0) 2022.11.22
spring boot 게시판 - 5 <thymeleaf layout 적용>  (0) 2022.11.21
spring boot 게시판 - 4 <spring security form login 구현>  (0) 2022.11.18
  1. ✅ 회원 정보 수정 <이름 변경>
  2. ✅ 회원 정보 수정 <비밀번호 변경>
  3. ✅ 회원 탈퇴
  4. ✅ 끝
'Java/Spring Boot 게시판' 카테고리의 다른 글
  • spring boot 게시판 - 9 <게시물 수정, 삭제>
  • spring boot 게시판 - 8 <게시물 작성, 조회>
  • spring boot 게시판 - 6 <bootstrap 적용하기>
  • spring boot 게시판 - 5 <thymeleaf layout 적용>
요술공주밍키
요술공주밍키
조금씩이라도 꾸준히..
  • 요술공주밍키
    삽질의흔적
    요술공주밍키
  • 전체
    오늘
    어제
    • 분류 전체보기 (131)
      • Java (42)
        • Spring Boot (14)
        • Spring Boot 게시판 (14)
        • 공중화장실 찾기 (4)
        • 쇼핑몰 (8)
      • JavaScript (8)
        • NodeJS (2)
      • Python (5)
        • Django (4)
      • Server (10)
        • Docker (4)
        • K8S (0)
        • Jenkins (1)
      • 알고리즘 (22)
        • 프로그래머스 (17)
        • 백준 (5)
      • Etc (21)
        • 개발 팁 (1)
      • 일상 (22)
        • 독서 포스트 (20)
        • 회고록 (2)
  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
요술공주밍키
spring boot 게시판 - 7 <회원 정보 수정 및 탈퇴>

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.