회원정보 수정
header.jsp
이제 회원정보 버튼을 눌렀을 때 수정할 수 있는 기능을 구현해야 한다.
그러면 /user/updateForm으로 가는 Controller를 작성해야 한다.
UserController에서 다음과 같이 /user/updateForm으로 가는 코드를 작성하였다.
/user/updateForm을 생성해보자
user폴더에 있는 joinForm을 복사해 붙여넣고 수정한다.
updateForm.jsp
username은 수정할 수 없게 readonly를 설정한다.
그리고 현재 header.jsp에 작성되어 있는 principal 코드를 이용해 updateForm에 value값을 줄 수 있다.
updateForm을 다음과 같이 작성한다.
principal을 이용해 value값을 설정하고 버튼의 id와 텍스트를 수정한다.
비밀번호는 value값을 주면 안되니까 빼준다.
그런데 이렇게 작성하면 비밀번호와 이메일만 넘기게 되는데 그러면 어떤 회원을 수정해야하는지 모르게된다.
따라서 여기서 히든값을 추가해 전달해주자
updateForm에 히든으로 유저의 id (primary key)를 같이 전달해준다.
이제 해당 id="btn-update" 버튼을 눌렀을 때 발생하는 자바스크립트를 작성하기 위해
user.js로 가자
user.js의 상단에 코드를 작성하고
아래에도 함수를 작성해준다.
이제 UserApiController로 가서
user에 값을 받아 userService의 회원수정에게 전달한다.
userService의 회원수정을 작성하면 된다.
JPA 영속성 컨텍스트 개념을 이용한다.
select로 이렇게 오브젝트를 들고 올 때 영속화가 된다.
영속화가 된 오브젝트를 변경하면 DB에 자동으로 update를 날려준다는 개념이다.
실행결과 :
이메일을 pinkbean@gmail.com에서 pinkbean2@gmail.com으로 바꿨다.
DB에서 user테이블을 확인해보니 잘 수정된 것을 확인할 수 있다.
이번엔 핑크빈의 비밀번호를 1234에서 12345로 변경해보았다.
비밀번호 값이 달라진 것을 확인할 수 있다.
실제로 로그인해봐도 1234에서 12345로 바뀐 것을 확인하였다.
회원수정 시 세션 값 변경
지금까지 회원정보 수정을 하면 DB에 update되면서 회원정보 수정이 문제없이 진행되지만
세션값은 변경이 되질 않았다.
세션값이 변경안되므로 before@gmail.com에서 after@gmail.com으로 수정하고
그 상태에서 다시 회원가입 버튼을 누르면 before@gmail.com로 화면에 떠있다.
로그아웃해야지 변경된 값을 확인할 수 있는 것이다.
따라서 직접 세션값을 변경해주자
변경해주는 방법은 시큐리티의 구조를 살펴보면 이해하기 쉽다.
SecurityContextHolder 안에 SecurityContext가 있다.
그리고 그 SecurityContext 안에 Authentication이라는 객체가 들어간다.
이 객체가 들어간 순간부터 세션에 값이 저장된 상태이다.
우선, 이 Authentication이 어떻게 만들어지는지부터 간략하게 살펴보자
시큐리티와 로그인 과정
사용자가 로그인 요청을 하게 되면 AuthenticationFilter를 거치게 된다.
이 AuthenticationFilter는 로그인 요청이 오면 이 필터가 제일 처음에 작동한다.
로그인 요청을 할 때 Http body에 username과 password를 달고 오는데,
이 2가지를 가지고 UsernamePasswordAuthenticationToken을 만든다.
그러면 AuthenticationManager라는 애가 그냥 username과 password를 받는 것이 아니라
UsernamePasswordAuthenticationToken이라는 객체를 받아서
AuthenticationManager가 Authentication이라는 객체를 만든다.
Authentication이라는 객체를 만드는 방법은, UsernamePasswordAuthenticationToken을
UserDetailService한테 던진다. 그럼 UserDetailService는 username을 가지고 데이터베이스에서
해당 username을 가진 유저가 있는지 확인한다.
있다면 Authentication라는 객체를 만들고, 없으면 만들지 않는다.
이 프로젝트에서 UserDetailService는
이것인데, 이제 UsernamePasswordAuthenticationToken이 UserDetailService인 이곳으로 들어오게 된다.
String username 으로 password말고 username만 들어와서 해당 유저로 DB에 사용자가 있는지 확인하고
있다면 이걸 principal에 담고 PrincipalDetail에 던져서 세션이 만들어지게 된다.
(참고로 password는 이쪽으로 오지 않고 스프링이 따로 가져가서 인코딩을 한다.
즉, AuthenticationManager는 UserDetailService로 username만 날린다.
그리고 password는 자신이 관리한다. BCrypt 인코드로 인코딩한다.
즉, 해당 유저를 찾는 작업은 UserDetailService가 하고 password 비교는 AuthenticationManager가 한다.
BCrypt 인코드로 인코딩해서 password비교를 한다.)
세션값 변경 코드 작성
시큐리티의 로그인 과정을 알았으니 이제 코드를 작성해보자
우선 username을 받아야 하니 user.js에서 다음 코드를 작성한다.
우선 AuthenticationManager가 필요하다.
이를 SecurityConfig에서 만들자
alt+shift+s를 눌러 다음 창이 뜨면 Override를 눌러준다.
authenticationManagerBean()을 체크하고 생성한다.
그럼 다음 코드가 작성된다.
*
@Bean : 개발자가 직접 제어가 불가능한 외부 라이브러리등을 Bean으로 만들려할 때 사용
@Component : 개발자가 직접 작성한 Class를 Bean으로 등록하기 위해 사용
이 프로젝트에선 UserService가 아니라 UserApiController에서 세션값 저장처리를 하기로 했다.
이제 UserApiController에서 AuthenticationManager를 Autowired하고
세션값이 변경되기 위해서는 SecurityContextHolder안의 SecurityContext 안에
Authentication이라는 객체가 들어간 순간부터 세션에 값이 저장된다고 하였다.
따라서 이렇게 SecurityContextHolder안에 SecurityContext에 Authentication 객체를 넣게되면
세션값이 저장되서 회원수정 시 제대로 화면에서 수정된 값이 뜨는 것을 확인할 수 있다.
실행결과
pinkbean2에서 다음과 같이 pinkbean으로 이메일을 변경했다.
바로 회원정보를 클릭해보니 변경한 이메일이 제대로 뜨는 것을 확인할 수 있다.
세션에 제대로 값이 저장된 것이다.
여기까지 회원수정이였다!
다음 시간엔 카카오 로그인 서비스를 공부해보도록 하겠다.
학습자료 :
'자바 스프링 > 부트 블로그 JPA 프로젝트' 카테고리의 다른 글
#29 OAuth2.0과 카카오 연동 로그인2 (로그인 서비스 완료) (1) | 2022.05.18 |
---|---|
#28 OAuth2.0과 카카오 연동 로그인1 (code와 AccessToken 받기) (1) | 2022.05.18 |
#26 CRUD 게시판 - Update, Delete (수정, 삭제) (0) | 2022.05.16 |
#25 CRUD 게시판 - Read (목록,페이징,상세보기) (2) | 2022.05.16 |
#24 CRUD 게시판 - Create (글 작성하기) (0) | 2022.05.15 |