회원정보 수정 페이지 만들기
updateForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="../layout/header.jsp"%>
<div class="container">
<form class="was-validated">
<input type="hidden" value="${principal.user.id }" id="id">
<div class="form-group">
<label for="uname">Username:</label> <input type="text" class="form-control" id="username" placeholder="아이디를 입력해주세요." name="username" value="${principal.user.username }" readonly>
</div>
<div class="form-group">
<label for="pwd">Password:</label> <input type="password" class="form-control" id="password" placeholder="비밀번호를 입력해주세요." name="password" required>
<div class="valid-feedback"></div>
<div class="invalid-feedback">수정할 비밀번호를 입력해주세요.</div>
</div>
<div class="form-group">
<label for="uname">Email:</label> <input type="text" class="form-control" id="email" placeholder="이메일 주소를 입력해주세요." name="email" value="${principal.user.email }">
<div class="valid-feedback"></div>
<div class="invalid-feedback">수정할 이메일을 입력해 주세요</div>
</div>
</form>
<button id="btn-update" class="btn btn-primary">회원정보 수정 완료</button>
</div>
<script src="/js/user.js"></script>
<%@ include file="../layout/footer.jsp"%>
UserController에 매핑 추가
@GetMapping("/user/updateForm")
public String updateForm() {
return "user/updateForm";
}
user.js에 update 메서드 추가
let index = {
init: function() {
$("#btn-save").on("click", ()=>{
this.save();
});
$("#btn-update").on("click", ()=>{
this.update();
});
},
save: function() {
let data = {
username: $("#username").val(),
password: $("#password").val(),
email: $("#email").val()
}; //javascript 오브젝트임.
//ajax 호출시 default가 비동기 호출
//ajax 통신을 이용하여 위의 data를 json으로 변경하여 insert 요청할 것임.
//ajax가 통신에 성공해서 서버가 json형태로 응답을 해주면 자동으로 자바 오브젝트로 변환해줌. (dataType을 지정하지 않아도.)
$.ajax({
//회원가입 수행 요청
type: "POST",
url: "/auth/joinProc",
data: JSON.stringify(data), //js object를 JSON형태로 변경. http body 데이터.
contentType: "application/json; charset=utf-8" //body 데이터의 타입 지정 (MIME)
//dataType: "json" //서버에서 응답이 올 때 문자열로 오는데 문자열 형태가 'json'이라면 => js object로 파싱 해줌.
}).done(function(resp){
alert("회원가입이 완료되었습니다.");
location.href="/";
}).fail(function(error){
alert(JSON.stringify(error));
}); //ajax 통신을 이용하여 3개의 데이터를 JSON으로 변경하여 insert 요청.
},
update: function() {
let data = {
id: $("#id").val(),
username: $("#username").val(),
password: $("#password").val(),
email: $("#email").val()
};
$.ajax({
type: "PUT",
url: "/user/update",
data: JSON.stringify(data), //js object를 JSON형태로 변경. http body 데이터.
contentType: "application/json; charset=utf-8", //body 데이터의 타입 지정 (MIME)
dataType: "json" //서버에서 응답이 올 때 문자열로 오는데 문자열 형태가 'json'이라면 => js object로 파싱 해줌.
}).done(function(resp){
alert("회원정보수정이 완료되었습니다.");
location.href="/";
}).fail(function(error){
alert(JSON.stringify(error));
});
}
/* login: function() {
let data = {
username: $("#username").val(),
password: $("#password").val(),
}; //javascript 오브젝트임.
$.ajax({
//회원가입 수행 요청
type: "POST",
url: "/api/user/login",
data: JSON.stringify(data), //js object를 JSON형태로 변경. http body 데이터.
contentType: "application/json; charset=utf-8", //body 데이터의 타입 지정 (MIME)
dataType: "json" //서버에서 응답이 올 때 문자열로 오는데 문자열 형태가 'json'이라면 => js object로 파싱 해줌.
}).done(function(resp){
alert("로그인이 완료되었습니다.");
location.href="/";
}).fail(function(error){
alert(JSON.stringify(error));
}); //ajax 통신을 이용하여 3개의 데이터를 JSON으로 변경하여 insert 요청.
}
*/
}
index.init();
UserApiController에 ajax요청을 받을 메서드 추가
@PutMapping("/user/update")
public ResponseDto<Integer> update(@RequestBody User user) {
userService.회원정보수정(user);
return new ResponseDto<Integer>(HttpStatus.OK.value(), 1);
}
UserService에 update메서드 추가
@Transactional
public void 회원정보수정(User user) {
// 수정시에는 User 오브젝트를 영속화시켜서 영속화된 User 오브젝트를 수정해야 함.
// 따라서 select문을 통해 User 오브젝트를 영속화시켜야 함.
// 영속화된 오브젝트를 수정하면 자동으로 DB에 업데이트 되는 특성을 이용하여 회원정보수정.
User persistance = userRepository.findById(user.getId())
.orElseThrow(() -> {
return new IllegalArgumentException("회원 찾기 실패");
});
String rawPassword = user.getPassword();
String encPassword = encoder.encode(rawPassword);
persistance.setPassword(encPassword);
persistance.setEmail(user.getEmail());
// 회원수정 함수 종료 == 서비스 종료 == 트랜잭션 종료 --> 자동 커밋 (더티체킹)
}
하지만. 이렇게까지만 해놓고 회원정보를 눌러서 회원정보수정 페이지에 다시 들어가보면 변경한 값이 아니라 기존 값으로 출력 되는 문제가 발생함.
이는 아직 시큐리티의 세션값이 변경되지 않았기 때문임. 세션값은 새로 로그인 할때마다 생성되기 때문.
이제 세션값을 변경시켜주는 작업을 할거임.
로그인 요청이 오면 인증 필터를 거쳐서 인증 토큰이 만들어짐.
토큰이 AuthenticationManager에 넘어가고 이 놈이 UserDetailsService를 통해서 DB 데이터를 확인하고
통과되면 Manager가 Authentication을 생성해서 시큐리티 컨텍스트에 넘겨주는 구조.
UserApiController 에서 강제로 세션에 변경된 DB값을 넣어준다.
AuthenticationManager를 빈 등록 하기 위해 SecurityConfig 수정
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
// TODO Auto-generated method stub
return super.authenticationManagerBean();
}
그리고 UserApiController 수정
package com.pure.blog.controller.api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.pure.blog.dto.ResponseDto;
import com.pure.blog.model.User;
import com.pure.blog.service.UserService;
@RestController
public class UserApiController {
@Autowired
private UserService userService;
@Autowired
private AuthenticationManager authenticationManager;
@PostMapping("/auth/joinProc")
public ResponseDto<Integer> save(@RequestBody User user) {
System.out.println("UserApiController: save 호출됨");
int result = userService.회원가입(user);
return new ResponseDto<Integer>(HttpStatus.OK.value(), result); //(status, data)
}
@PutMapping("/user/update")
public ResponseDto<Integer> update(@RequestBody User user) {
userService.회원정보수정(user);
//여기까지 하면 DB값 변경 됨.
// DB값 변경 이후의 user 값으로 세션 등록
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
return new ResponseDto<Integer>(HttpStatus.OK.value(), 1);
}
}
authentication의 내용을 강제로 수정한 값으로 바꾸고
세션이 들어있는 SecurityContextHolder안의 Context에 바꾼 authentication을 넣어준다.
'취업 준비 > Spring boot' 카테고리의 다른 글
37. 카카오 로그인 REST API 방식 (0) | 2022.01.31 |
---|---|
36. 카카오 로그인 준비 (0) | 2022.01.29 |
34. 글 수정 (0) | 2022.01.28 |
33. 글 삭제 (0) | 2022.01.27 |
32. 글 상세내용 보여주기 (0) | 2022.01.27 |