유저대 클럽 N:1 관계이고
클럽을 삭제할라면 그 클럽의 주인(클럽을 만든사람)이여야만 가능한 서비스 로직이다
그래서 기존의 코드는 다음과 같은데..
var position = clubPositionService.findUserPosition(clubId, userId);
if(position.getType() != ClubPositionType.ADMIN) {
throw new ForbiddenException("관리자만 동아리를 폐쇄할 수 있어요.");
}
이 부분이 너무 거슬려서 어떻게 뺄 수 없나.. 그리고 클럽장인지 확인하는 로직은 이부분말고도 많은 클럽과 의존하고 있는 모듈에서 쓰이니깐
저 로직을 밖으로 빼버리고 싶었다
스프링 AOP를 활용하면 되지 않을 까 싶었는데
관련해서 학습할 것들의 난이도가.. 쉽지 않아보이고
실제 운영되는 서비스이고 프로젝트라서 여기다 나만의 실험실을 차릴 순 없겠다 싶어서 그냥 일단은 다른 방법을 찾아보았다
스프링 AOP는 다음프로젝트때 적용해보기로 하고..!
스프링 시큐리티에서 제공하는 메서드 시큐리리 중 하나인 @PreAuthorize()를 사용했다
지원하는 것들은 다음과 같다
@Secured
@RolesAllowed
@PreAuthorize
@PostAuthorize
@PreFilter
@PostFilter
이것들 중 일단은 특정 서비스 함수를 실행하기 전에 권한을 체크할 것이므로 @PreAuthorize를 사용한다
사용 전과 후를 비교해보면..!
1.일단 가독성을 따져본다면 위에 것이 좀 더 깔끔해 보인다..
2.많이 사용되는 로직을 밖으로 빼내서 재사용성을 올려버렸다
3. deleteUserClub은 UserClubService의 함수였는데
이때 UserClubService에서 clubMemberService 또는 clubPositionService(사진의 예)를 의존하고 있었다 (패키지참조)
어차피 @Service는 .. 빈 컨테이너에 계속 등록되어있으니깐
............
솔직히 이부분 잘 모르겠따!
SpEL(Spring Expression Language) 를 공부해 봐야겠다
결론은 의존관계는 변하지 않는다
그냥 코드가 깔끔해졌다 그게 다인거 같다
custom annotation 만들면 된다.
주의할 점이 @ClubPresident 붙이는 함수의 파라미터 변수명과
SpEL에 넘겨주는 변수명이 같아야한다
진짜 모르겠다
@Preauthorize에서 false 반환하면 그냥 accessDeniedException 터지는데 모든 false 에 대해서 저것만 반환하니깐 유저한테 정확히 어떤 이유로 터졌는지 알려줄 수 있는 방법을 못찾겠다..
그래서 그냥
일단은 이렇게 했다..
이게 맞는 설계 또는 방식인지 아직은 잘 모르겠다 그리고 저 exception 처리하는 것도 좀 파봐야겠다 ㅠㅠ
https://www.baeldung.com/spring-security-method-security
https://www.baeldung.com/exception-handling-for-rest-with-spring#errorPage