have a good time 2021. 12. 11. 20:50

<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();
	}

}