Auditing 적용

뚜우웅이·2025년 3월 24일

캡스톤 디자인

목록 보기
2/35

작성일시, 수정일시, 작성자, 수정자 등을 모든 entity에 추가하기에는 코드가 길어질 수 있어 따로 분리하여 작성하기 위해 Auditing을 사용해준다.

Application

@SpringBootApplication
@EnableJpaAuditing
public class FreeMarketApplication {

	public static void main(String[] args) {
		SpringApplication.run(FreeMarketApplication.class, args);
	}

	// AuditorAware 빈 등록 - 현재 인증된 사용자의 ID를 제공
	@Bean
	public AuditorAware<Long> auditorProvider() {
		return new AuditorAwareImpl();
	}
}

CustomUserDetails

@Getter
public class CustomUserDetails implements UserDetails {

    private final Long userId;
    private final String email;
    private final String password;
    private final String role;
    private final boolean enabled;

    public CustomUserDetails(Long userId, String email, String password, String role, boolean enabled) {
        this.userId = userId;
        this.email = email;
        this.password = password;
        this.role = role;
        this.enabled = enabled;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        // role 값에 "ROLE_" 접두사가 없으면 추가
        String authority = this.role.startsWith("ROLE_") ? this.role : "ROLE_" + this.role;
        return Collections.singleton(new SimpleGrantedAuthority(authority));
    }

    @Override
    public String getPassword() {
        return this.password;
    }

    @Override
    public String getUsername() {
        // Spring Security의 username으로 email을 사용
        return this.email;
    }

    @Override
    public boolean isAccountNonExpired() {
        // 계정 만료 여부: true는 만료되지 않음을 의미
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        // 계정 잠금 여부: true는 잠기지 않음을 의미
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // 자격 증명 만료 여부: true는 만료되지 않음을 의미
        return true;
    }

    @Override
    public boolean isEnabled() {
        // 계정 활성화 여부
        return this.enabled;
    }
}

CustomUserDetails 클래스는 이후 Security 관련 코드에서도 사용할 것이다.

AuditorAwareImpl

public class AuditorAwareImpl implements AuditorAware<Long> {

    @Override
    public Optional<Long> getCurrentAuditor() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        // 인증 정보가 없거나 인증되지 않은 경우
        if (authentication == null || !authentication.isAuthenticated()) {
            return Optional.empty();
        }

        // 인증된 사용자 정보 추출
        Object principal = authentication.getPrincipal();
        if (principal instanceof CustomUserDetails) {
            CustomUserDetails userDetails = (CustomUserDetails) principal;
            return Optional.of(userDetails.getUserId());
        }

        return Optional.empty();
    }
}

Security에서 사용자 정보를 추출하여 작성자, 수정자로 표시를 해준다.

BaseTimeEntity

@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseTimeEntity {

    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime updatedDate;
}

BaseEntity

@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseEntity extends BaseTimeEntity {

    @CreatedBy
    @Column(updatable = false)
    private Long createdBy;

    @LastModifiedBy
    private Long modifiedBy;
}
profile
공부하는 초보 개발자

0개의 댓글