회원정보 수정 기능은 사용자의 입력 값으로 DB의 정보를 최신화 시킨 다음
최신화된 DB정보를 바탕으로 스프링 시큐리티의 로그인 로직을 내부적으로 실행시켜 세션의 로그인 정보를 최신화 하는 방법으로 구현되었습니다.
외부 자바스크립트 코드를 통하여 Ajax 통신을 진행할 것이기 때문에 button을 form태그 밖에서 작성합니다.
input 태그의 id 값을 통해 입력값과 외부 자바스크립트 변수를 매핑해 줄 것 입니다.
<div class="container" style="margin-bottom: 1rem">
<form>
<div class="mb-3 mt-3">
<label for="username" class="form-label">UserName:</label>
<input type="text" class="form-control" id="username"
th:value="${#authentication.principal.user.username}"
name="username" readonly>
</div>
<div th:if="${#authentication.principal.user.oauth == null}" class="mb-3">
<label for="password" class="form-label">Password:</label>
<input type="text" class="form-control" id="password"
placeholder="Enter password" name="password">
</div>
<div th:if="${#authentication.principal.user.oauth == null}" class="mb-3 mt-3">
<label for="email" class="form-label">Email:</label>
<input type="email" class="form-control" id="email"
th:value="${#authentication.principal.user.email}"
placeholder="Enter email" name="email">
</div>
<div th:unless="${#authentication.principal.user.oauth == null}"
class="mb-3 mt-3">
<label for="email" class="form-label">Email:</label>
<input type="email" class="form-control"
th:value="${#authentication.principal.user.email}"
placeholder="Enter email" name="email" readonly>
</div>
</form>
<button id="btn-update" class="btn btn-primary">회원정보 수정</button>
</div>
<script type="text/javascript" th:inline="javascript">
const updateUserId = $.parseJSON('[[ ${#authentication.principal.user.id} ]]');
</script>
/user 로 HttpBody
에 json
형식으로 데이터를 담아 PUT
요청을 보냅니다.
update: function (){
let data = {
id: updateUserId,
username: $("#username").val(),
password: $("#password").val(),
email: $("#email").val()
}
$.ajax({
type: "PUT",
url: "/user",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json",
}).done(function (response) {
// 요청 결과가 정상인 경우
const status = response.status;
if (status === 200){
alert("회원정보 수정이 완료 되었습니다.");
location.href = ("/");
} else {
alert(response.data);
}
}).fail(function (error) {
// 요청 결과가 비정상인 경우
alert(JSON.stringify(error));
}); // ajax 통신을 이용해서 3개의 데이터를 json 으로 변경하여 insert 요청
}
회원 정보를 수정했을 시 스프링시큐리티 내부에서 새로운 정보를 토대로 재로그인이 실행되고 최신의 정보가 세션에 저장될 수 있도록 코드를 작성합니다.
@PutMapping("/user")
public ResponseDTO<Integer> update(@RequestBody User user){
userService.update(user);
// 서비스가 종료되면서 트랜잭션도 종료되어 DB의 값은 변경되지만
// 시큐리티 세션의 정보는 변경 되지 않은 상태이기 때문에 직접 세션의 값 변경이 필요하다.
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
return new ResponseDTO<Integer>(HttpStatus.OK.value(), 1);
}
새로운 User 객체를 생성하여 영속화 시킵니다.
이후 요청된 값의 유효성을 체크한 뒤 트랜잭션을 종료시키며 데이터베이스에 Commit 합니다.
@Transactional
public void update(User requestUser) {
User persistenceUser = userRepository.findById(requestUser.getId()).orElseThrow(() -> {
throw new IllegalArgumentException("회원수정 실패: 회원 정보가 존재하지 않습니다.");
});
//validate 체크
if (persistenceUser.getOauth() == null || persistenceUser.getOauth().equals("")) {
persistenceUser.setPassword(encoder.encode(requestUser.getPassword()));
persistenceUser.setEmail(requestUser.getEmail());
}
}