커뮤니티 프로젝트

회원정보 수정

쭈녁 2022. 11. 30. 18:47
   @GetMapping("/update")
    public String update(Model model, @AuthenticationPrincipal PrincipalDetail principalDetail) {
        model.addAttribute("member", principalDetail.getMember());
        return "users/updateForm";
    }

    @Transactional
    @PostMapping("/update")
    public String update(@ModelAttribute MemberUpdateDto memberUpdateDto, @AuthenticationPrincipal PrincipalDetail principalDetail, RedirectAttributes redirectAttributes) {
        Integer memberId = principalDetail.getMember().getId();
        String rawPassword = memberUpdateDto.getPassword();
        String encPassword = bCryptPasswordEncoder.encode(rawPassword);
        memberUpdateDto.setPassword(encPassword);
        memberRepository.update(memberId, memberUpdateDto);
        return "redirect:/users/update";
    }

HTML

 <h2>정보수정</h2>
    </div>
    <h4 class="mb-3">회원 정보 입력</h4>
    <form action="post" th:action method="post">

        <div>
            <label for="loginId" class="sr-only">로그인 아이디</label>
            <input type="text" th:value="${#authentication.principal.username}" class="form-control" id="loginId"
                   placeholder="아이디를 입력하세요." required
                   minlength="4" size="20" readonly>
            <!--            <div class="invalid-feedback" th:if="${#fields.hasErrors('loginId')}" th:errors="*{loginId}">-->
            <!--                중복회원-->
            <!--            </div>-->
        </div>
        <div>
            <label for="password" class="sr-only">비밀번호</label>
            <input type="password" class="form-control" id="password" placeholder="패스워드를 입력하세요." required
                   minlength="8" size="20">


            <div>
                <label for="nickName">닉네임 </label>
                <input type="text" th:value="${#authentication.principal.nickName}" class="form-control" id="nickname"
                       placeholder="닉네임을 입력하세요." required
                       minlength="4" size="20">

                <div>
                    <label for="email">이메일</label>
                    <input type="email" th:value="${#authentication.principal.email}" class="form-control" id="email"
                           placeholder="이메일을 입력하세요." required readonly>

                    <div>
                        <label for="profile">내 프로필</label>
                        <input type="text" th:value="${#authentication.principal.profile}" class="form-control"
                               id="profile" placeholder="프로필을 입력하세요." required
                               minlength="4" size="20">

                        <hr class="my-4">
                        <div class="row">
                            <div class="col">
                                <button class="w-100 btn btn-lg btn-success" type="submit">회원수정</button>
                            </div>
                            <div class="col">
                                <button class="w-100 btn btn-secondary btn-lg"
                                        onclick="location.href='posts.html'"
                                        th:onclick="|location.href='@{/}'|"
                                        type="button">취소
                                </button>

th:value="${#authentication.principal.username}" 를 사용하여 스프링 시큐리티로 들어오는 유저 정보를 넣어주었다.

 

Controller

    @GetMapping("/update")
    public String update(@ModelAttribute MemberUpdateDto memberUpdateDto, @AuthenticationPrincipal PrincipalDetail principalDetail) {
        return "users/updateForm";
    }

    @Transactional
    @PostMapping("/update")
    public String update(@ModelAttribute MemberUpdateDto memberUpdateDto, @AuthenticationPrincipal PrincipalDetail principalDetail, RedirectAttributes redirectAttributes) {
        Integer memberId = principalDetail.getMember().getId();
        String rawPassword = memberUpdateDto.getPassword();
        String encPassword = bCryptPasswordEncoder.encode(rawPassword);
        memberUpdateDto.setPassword(encPassword);
        memberRepository.update(memberId, memberUpdateDto);
        return "redirect:/users/update";
    }

컨트롤러에서는 들어온 memberUpdateDto의 정보 중 비밀 번호를 인코딩하여 업데이트 하도록 작성하였다.

 

작업을 완료하고 돌려보는데 memberUpdateDto에 데이터들이 Null값으로 들어오고 있었다.

log를 통한 확인 결과

아마 모델로 프론트에 던져준 객체에 정보를 채워 오지 못하는 이슈가 있는 것 같은데 하루 종일 잡고 봤는데도 아직 해결하지 못했다. 아마 HTML 문서에 오류가 있어 Model을 받지 못하는 것 같다...

유튜브 강의등 많은 자료들이 JSP를 사용하여 작성된 프로젝트들이 많아 내 프로젝트에 맞게 찾아보면서 작업하고 있는데 이점이 쉽지 않은것 같다... 이 프로젝트가 끝나면 JSP와 자바스크립트를 추가한 프로젝트를 진행해 보아야 할 것 같다...

 

 

 

 

 

========================================================================

수정 사항

========================================================================

 

HTML 문서 내에서 시큐리티가 가지고 있는 유저 정보와 sumit받으려는 Member객체를 모두 넣는 방법을 찾기 어려워 나름 컨트롤러 단에서 해결해 보았다 해결 방법은 아래와 같다.

 

HTML

   <h2>정보수정</h2>
    </div>
    <h4 class="mb-3">회원 정보 입력</h4>
    <form action="post" th:action th:object="${member}" method="post">

        <div>
            <label for="loginId" class="sr-only">로그인 아이디</label>
            <input type="text" th:field="*{loginId}" class="form-control" id="loginId"
                   placeholder="아이디를 입력하세요." required
                   minlength="4" size="20" readonly>
            <div class="invalid-feedback" th:if="${#fields.hasErrors('loginId')}" th:errors="*{loginId}">
                중복회원
            </div>
        </div>
        <div>
            <label for="password" class="sr-only">비밀번호</label>
            <input type="password" class="form-control" th:field="*{password}" id="password" placeholder="패스워드를 입력하세요." required
                   minlength="8" size="20">


            <div>
                <label for="nickName">닉네임 </label>
                <input type="text" th:field="*{nickName}" class="form-control" id="nickname"
                       placeholder="닉네임을 입력하세요." required
                       minlength="4" size="20">
                <div class="field-error" th:errors="*{nickName}"/>
            </div>
            <div>
                <label for="email">이메일</label>
                <input type="email" th:field="*{email}" class="form-control" id="email"
                       placeholder="이메일을 입력하세요." required readonly>
                <div class="field-error" th:errors="*{email}"/>
            </div>
            <div>
                <label for="profile">내 프로필</label>
                <input type="text" th:field="*{profile}" class="form-control"
                       id="profile" placeholder="프로필을 입력하세요." required
                       minlength="4" size="20">
                <div class="field-error" th:errors="*{profile}"/>
            </div>
            <hr class="my-4">
            <div class="row">
                <div class="col">
                    <button class="w-100 btn btn-lg btn-success" type="submit">회원수정</button>
                </div>
                <div class="col">
                    <button class="w-100 btn btn-secondary btn-lg"
                            onclick="location.href='/'"
                            th:onclick="|location.href='@{/}'|"
                            type="button">취소
                    </button>

기존 th:value="${#authentication.principal.username}" 을 통해 PrincipalDetail의 시큐리티가 가지고 있는 유저정보를 가지고 왔었다. 하지만 이 경우에 value에 PrincipalDetail가 들어가 수정하려는 Member 객체가 아닌 다른 값이 value값이 되는 부분을 수정 하기 위해 Controller에서 아래와 같이 수정하였다.

 

memberController

   @GetMapping("/update")
    public String update(Model model, @AuthenticationPrincipal PrincipalDetail principalDetail) {
        model.addAttribute("member", principalDetail.getMember());
        return "users/updateForm";
    }

    @Transactional
    @PostMapping("/update")
    public String update(@ModelAttribute MemberUpdateDto memberUpdateDto, @AuthenticationPrincipal PrincipalDetail principalDetail, RedirectAttributes redirectAttributes) {
        Integer memberId = principalDetail.getMember().getId();
        
        String rawPassword = memberUpdateDto.getPassword();
        String encPassword = bCryptPasswordEncoder.encode(rawPassword);
        memberUpdateDto.setPassword(encPassword);
        memberRepository.update(memberId, memberUpdateDto);
        return "redirect:/users/update";
    }

처음 update의 URL로 접근할 때 (@AuthenticationPrincipal PrincipalDetail principalDetail) 를 통해 로그인 된 사용자의 유저 정보를 가지고 온다. 그 후 수정 폼에 들어갈 Model에 해당 정보를 Member로 받아 addAtrribute 해준다.

 

기존엔 빈 Member객체를 Model에 addAtrribute하여 빈객체에 수정될 정보를 받아왔다면, 내가 이후 수정한 방법에서는

로그인한 유저의 객체를 모델에 넣음으로

모델을 생성함 과 동시에 로그인된 유저 정보를 회원 수정 폼에서 확인 할 수 있도록 수정 하였다.

 

결과

수정 폼에 로그인 한 사용자의 정보를 그대로 가져옴
로그에 수정하나 비밀번호 닉네임 프로필이 잘 들어옴

 

우려사항

 

controller에서 update URL로 접근할 때 고객 정보를 담은 객체를 넣는 것이 보안상 문제가 될지 안될지는 잘 모르겠으나

애초에 해당 URL까지 접근하기까지 로그인이 된 사용자만 갈수 있도록 설정하였고 해당 사용자의 상세 내용을 제공하는것임으로 문제가 없을 것 같다는 생각(아직까진)