회원정보 수정 1
<UserController.java> 파일
@GetMapping("/user/{id}/update")
public String update(@PathVariable int id, @AuthenticationPrincipal PrincipalDetails principalDetails, Model model) {
model.addAttribute("principal", principalDetails.getUser());
return "user/update";
}
세션에 저장된 로그인 사용자의 정보를 사이트 화면에 뿌려보려고 한다.
(예를 들어 사용자의 username 값이 hi 라면 hi를 화면에 보이도록)
1. model 사용
그래서 위와 같이, @AuthenticationPrincipal 애노테이션을 활용해서 세션에 저장된 사용자 정보를
principal 이라는 변수명으로 model 에 담아준다.
model.addAttribute("principal", principalDetails.getUser());
이렇게 model 에 담아주면, return "user/update"
즉, update.jsp 파일에서 사용할 수 있다.
그래서 만약에 update.jsp 파일에서
<h2>${principal.username}</h2>
이렇게 사용하면,
${principal.username} 이 부분으로 사용할 수 있다.
즉, 위의 model에서 principal 이라는 이름으로 전달해 주었기 때문에
여기서도 principal이라는 이름을 사용하는데,
principal은 PrincipalDetails.getUser() 값을 의미한다.
${principal.username} 이렇게 사용하는 것을 jsp 의 el 표현식이라고 하며,
principal.username 하면 알아서 getter가 호출되서
이는, principal.getUsername 하는 것과 같음
(<h2> 태그는 html 관련 태그임)
결국
User.java의 변수 값들을 get 하여 사용할 수 있으므로,
<User.java> 파일
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(length = 100, unique = true)
private String username;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String name;
private String website; // 웹 사이트
private String bio; // 자기 소개
@Column(nullable = false)
private String email;
private String phone;
private String gender;
private String role; // 권한
private String profileImageUrl;
private LocalDateTime createDate;
@PrePersist
public void createDate() {
this.createDate = LocalDateTime.now();
}
}
${principal.username}
이렇게 사용한다면, User.java에 있는 username 변수의 값을 가져다 사용할 수 있다.
그래서 사용자의 username 이 만약 hi 라면,
화면에 아래처럼 결과값을 나타낼 수 있다.
(<h2>${principal.username}</h2> 이 코드의 결과임)
회원정보 수정 페이지가 아래와 같이 되어 있는데, 여러가지 값들을 위처럼 가져다가 사용할 수 있다.
위의 화면은 update.jsp 파일에서 나타내는 모습으로,
위에 이메일이 hi@com 으로 되어 있는데,
이 역시 아래처럼 value 부분에 ${principal.email} 이렇게 되어 있어서,
사용자의 정보를 가져다가 표시한 것이다.
<update.jsp 파일>
<div class="content-item__08">
<div class="item__title">이메일</div>
<div class="item__input">
<input type="text" name="email" placeholder="이메일"
value="${principal.email}" readonly="readonly" />
</div>
</div>
특히 여기서는 readonly = "readonly"라고 되어 있어서, 값이 변경 안됨.
변경할 수 있게 하려면, readonly 부분 삭제
그런데 이런 방법 말고, security taglib 를 이용해서 쉽게 사용할 수 있는 방법이 있어서 설명
2. security-taglibs 사용
pom.xml 파일에 추가
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
</dependency>
jsp 파일 위에 추가
<sec:authorize access="isAuthenticated()">
<sec:authentication property="principal" var="principal"/>
</sec:authorize>
isAuthenticated() : 인증된 정보에 접근 (세션에 접근)
property = "principal" : 세션 정보에 접근 가능
위 내용은 키워드이기 때문에 그대로 사용
우리가 수정할 부분은
var = "principal"
이 부분.
즉 property = "principal" 값을
어느 변수에 담아서 사용할지 정해주는 거임.
우리는 principal 이라는 변수에 담아서 사용할 거임
그러면 jsp 파일 어디서든
${principal} 이렇게 적으면
PrincipalDetails 에 접근 가능
principalDetails 에 대해 알고 싶다면 아래 내용 참고 (읽을 내용 많음)
https://happy-fun.tistory.com/159
로그인
보통 스프링 시큐리티를 적용하면 어느 페이지로 이동하건 시큐리티 로그인을 요구한다고 설명했다. 자세한 설명은 아래 자료 참고 https://happy-fun.tistory.com/153 스프링 시큐리티 세팅 스프링 시큐
happy-fun.tistory.com
때문에 이제는 UserController.java에서 model 매개변수 제거해도 됨
단, PrincipalDetails의 user객체를 먼저 불러와야 하기 때문에,
jsp 파일에서
${principal.user.name}
이런식으로, user를 불러온 다음에, user의 name 값을 사용하던지 해야함.
위의 1번에서는, (model 을 이용하는)
principal 이, PrincipalDetails.getUser를 의미하는 거였어서, user를 또 불러오지 않았지만,
여기서의 principal 은 PrincipalDetails를 의미하므로, user를 불러와야 함
<PrincipalDetails.java> 파일
즉, 여기에 있는 private User user; 객체 변수를 사용해서, 아래의 User.java 파일의 변수들에 접근
@Data
public class PrincipalDetails implements UserDetails{
private static final long serialVersionUID = 1L;
private User user;
public PrincipalDetails(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> collector = new ArrayList<>();
collector.add(() -> { return user.getRole();});
return collector;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
<User.java> 파일
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(length = 100, unique = true)
private String username;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private String name;
private String website; // 웹 사이트
private String bio; // 자기 소개
@Column(nullable = false)
private String email;
private String phone;
private String gender;
private String role; // 권한
private String profileImageUrl;
private LocalDateTime createDate;
@PrePersist
public void createDate() {
this.createDate = LocalDateTime.now();
}
}