본문 바로가기

TIL(Today I Learned)

TIL-230830(항해99 실전 프로젝트-행동대장(20))

📝오늘 공부한 것

  • 실전프로젝트 - '행동대장' 마이페이지 구현

 

📌 마이페이지

카카오로그인 시 이메일제공에 동의하지 않고 가입하는 유저는 이메일에 대한 정보가 들어오지 않아 DB에 저장을 할 수 없다.

그런데 우리 프로젝트에서 알림기능을 추가로 구현하기로 하였다. 사이트에서의 알림뿐만 아니라 '해결했어요'가 5개 넘으면 게시글이 완료처리되면서 완료되었다는 알림을 이메일로 보내는 기능을 추가하였다. 그런데 이메일이 없는 카카오유저에게는 이메일이 가지 않아, 나중에 받고 싶어도 받을 수 있는 방법이 없기 때문에 이메일을 따로 받게 하자고 하였다.

그래서 이메일을 따로 등록하는 기능을 만들기 보다는 마이페이지를 만들어서 그 기능을 추가하자는 의견이 나왔다.

 

 마이페이지에는 이메일 추가등록, 닉네임 변경, 비밀번호 변경, 회원탈퇴 기능을 넣기로 하였다.

 닉네임 변경은 카카오 유저의 경우 따로 닉네임을 설정할 수 없고, 카카오에서 설정한 닉네임으로 가입이 된다. 그리고 일반유저와의 닉네임 중복문제를 위해 카카오닉네임 + _KAKAO + kakaoId로 설정이 된다. 따라서, 닉네임 변경 기능이 필요하다고 생각했다.

 

✔ MyPageService

    //닉네임 수정
    @Transactional
    public CommonResponse updateNickname(UpdateNicknameRequestDto requestDto, User user) {
        String newNickname = requestDto.getNickname();

        Optional<User> existingUserWithNewNickname = userRepository.findByNickname(newNickname);
        if (existingUserWithNewNickname.isPresent()) {
            throw new MyPageException(ClientErrorCode.DUPLICATE_NICKNAME);
        }

        user.updateNickname(newNickname);
        userRepository.save(user);

        return new CommonResponse(UPDATE_NICKNAME);
    }

 

 

 비밀번호 변경은 현재비밀번호와 같은 번호로 바꾸면 변경 불가 VS 현재비밀번호와 같은 번호로 바꿔도 변경완료시키기 중에 현재비밀번호와 같은 번호로 바꿔도 변경완료시키기로 하였다. 우리 사이트의 경우 가볍게 가입한 유저가 많을 것이고, 그렇다면 처음에 설정했던 비밀번호를 금방 잊어버릴수도 있다고 생각한다.  현재비밀번호와 같은 번호로 바꾸면 변경 불가의 로직을 구현하려면 현재비밀번호도 같이 입력받아야했다. 그런데 현재비밀번호가 생각이 나지 않으면 비밀번호를 변경할 수 가 없는 것이었다! 그래서 현재비밀번호와 상관없이 바꿔주기로 하였다.

 

✔ MyPageService

    //비밀번호 변경
    @Transactional
    public CommonResponse updatePassword(UpdatePasswordRequestDto requestDto, User user) {
        String newPassword = passwordEncoder.encode(requestDto.getPassword());

        userRepository.findByNickname(user.getNickname()).orElseThrow(
                ()-> new MyPageException(ClientErrorCode.NO_ACCOUNT));

        user.updatePassword(newPassword);
        userRepository.save(user);
        return new CommonResponse(UPDATE_PASSWORD);
    }

 

알게 된 점

회원탈퇴 기능 구현 시 orphanRemoval = true와 CascadeType.REMOVE 중 어떠한 걸 써야하는지 헷갈렸다.

 

CascadeType.REMOVE

 - 부모 entity가 삭제되면 자식 entity도 삭제된다. 즉, 부모가 자식의 삭제 생명 주기를 관리한다.

 - 부모 entity와 자식 entity의 연관관계를 제거해도, 자식 entity는 삭제되지 않고 DB에 남아있는다.

 

orphanRemoval = true

 - 부모 entity가 삭제되면 자식 entity도 삭제된다. 즉, 부모가 자식의 삭제 생명 주기를 관리한다.

 - 부모 entity와 자식 entity의 연관관계를 제거해도, 자식 entity는 고아 객체로 취급되어 DB에서 삭제된다.

 

😥어려웠던 것들

처음에 비밀번호 변경 로직을 구현하려고 할 때 현재비밀번호와 일치하는 비밀번호로 변경하는 경우 예외를 날려주려고 하였다. 그래서 단순히 바꾸려는 비밀번호를 입력하면 encoding하여 DB에 있는 인코딩된 현재비밀번호와 비교하면 되겠다!하고 생각했었다. 로직을 구현하고 fostman으로 확인했을때 같은 비밀번호로 입력했는데도 현재비밀번호와 일치한다는 예외메시지가 나오지 않고 비밀번호가 변경되었다는 메시지가 나오는 것이었다!

그래서 구글링을 해봤더니 같은 문자열을 인코딩할 때마다 결과값이 매번 달라진다는 것이었다.ㅠㅠ

그래서 유저에게 현재비밀번호를 같이 입력받아 passwordEncoder.matches의 메서드를 이용하면 비교가 가능하다는 것을 알았다. 이번에는 사용하지 않았지만, 다음에 로직을 구현한다면 이방법을 사용해봐야겠다.