Auditing
@CreatedDate
private Date created;
@LastModifiedDate
private Date updated;
@CreatedBy
@ManyToOne
private Account createdBy;
@LastModifiedBy
@ManyToOne
private Account updatedBy;
메인 애플리케이션 위에 @EnableJpaAuditing
추가
@EnableJpaAuditing
@SpringBootApplication
public class Application {
엔티티 클래스 위에 @EntityListeners(AuditingEntityListener.class)
추가
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class TimeStamp {
@CreatedDate
private LocalDateTime createdAt;
@CreatedBy
@ManyToOne
private User createdBy;
@LastModifiedDate
private LocalDateTime modifiedAt;
@LastModifiedBy
@ManyToOne
private User modifiedBy;
}
persistence
가 같이 유지됨AuditorAware 구현체 만들기
SecurityContextHolder
에서 인증정보안에 담긴 UserDetailsImpl
을 사용하여 user 객체를 가져와서 넣어준다.// JwtAuthFilter.java
@Slf4j
@RequiredArgsConstructor
public class JwtAuthFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String token = jwtUtil.resolveToken(request);
if(token != null) {
if(!jwtUtil.validateToken(token)){
jwtExceptionHandler(response, "Token Error", HttpStatus.UNAUTHORIZED.value());
return;
}
Claims info = jwtUtil.getUserInfoFromToken(token);
// 인증정보 세팅함수 호출
setAuthentication(info.getSubject());
}
try {
filterChain.doFilter(request, response);
}catch(FileUploadException e){
jwtExceptionHandler(response,"File Upload Error",400);
}
}
public void setAuthentication(String username) {
// SecurityContextHolder 는 threadLocal 로 구현되어 요청쓰레드내에서 공유할 수 있다.
SecurityContext context = SecurityContextHolder.createEmptyContext();
Authentication authentication = jwtUtil.createAuthentication(username);
// 요기서 인증정보(계정정보)를 담아준다.
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
}
...
}
@Service
public class UserAuditorAware implements AuditorAware<User> {
@Override
public Optional<User> getCurrentAuditor() { //AuditorAware의 getCurrentAuditor() 메서드를 구현
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); //인증정보를 받아옴
if (authentication == null || !authentication.isAuthenticated()) {
return Optional.empty();
}
return Optional.of(((UserDetailsImpl) authentication.getPrincipal()).getUser());
}
}
@EnableJpaAuditing에 AuditorAware 빈 이름 설정하기.
생성 > 수정 > 삭제
이 흐름을 엔티티 라이프 사이클 이벤트라고 한다.전 : @PrePersist
: EntityManager 가 엔티티를 영속성상태로 만들기 직전에 메소드 수행
후 : @PostPersist
: EntityManager 가 엔티티를 영속성상태로 만든 직후에 메소드 수행
전 : @PreUpdate
: EntityManager 가 엔티티를 갱신상태로 만들기 직전에 메소드 수행
후 : @PostUpdate
: EntityManager 가 엔티티를 갱신상태로 만든 직후에 메소드 수행
전 : @PerRemove
: EntityManager 가 엔티티를 삭제상태로 만들기 직전에 메소드 수행
후 : @PostRemove
: : EntityManager 가 엔티티를 삭제상태로 만든 직후에 메소드 수행
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class TimeStamp {
@CreatedDate
private LocalDateTime createdAt;
@CreatedDate
private LocalDateTime modifiedAt;
}