2023. 1. 6. 01:01ㆍ기록/TIL
[TIL] Today I Lerned - 230105
230105 기록
프로젝트 - 리팩토링
- 프로젝트를 유지하면서 로직이나 가독성을 좋게 하기 위해 지속적으로 리펙토링을 진행하였다.
1. 수정 / 삭제의 코드 변경
- 기존의 수정 / 경우 해당 서비스 로직 내부에서 요청을 요구한 유저의 권한 || 요청을 한 당사자가 글의 주인인지 확인하는 과정을 거쳤다. 리펙토링을 진행하면서 해당 검사 로직을 각각의 board와 user에서 검사를 하고 해당 값을 boolean값으로 T/F 반환하는 형태로 변경하였다.
- 리펙토링을 진행하여 서비스단에서의 가독성 확보, 그리고 각 객체에서 객체에 값을 확인하는 서비스단의 의존성을 줄일 수 있었다.
if (board.getUser().getId() == user.getId() || user.getUserRoleEnum().equals(UserRoleEnum.ADMIN)) {
board.update(requestDto);
return new BoardResponseDto(board);
} else {
throw new IllegalArgumentException("해당 사용자 혹은 관리자가 아니면 게시글을 수정할 수 없습니다!");
}
}
이전의 프로젝트에서 진행을 했던 service코드가 이것이었다. 이부분은 board에서 값을 가져와서 비교를 하고 넣어주는 방식으로 해당 service에서 주어진 일을 처리하기 위해 작성자 검사라는 일을 하나 더 하게 되는 경우가 된다.
다만 SOLID의 단일 책임원칙, 그리고 저러한 검사의 역할은 board와 user에서 해주는것이 좋다는 조언을 들어서 해당 로직을 상의 후 다음과 같이 변경
// BoardService - 사용자 인증 과정
if (board.isWriter(user.getId())) {
board.update(requestDto);
return new BoardResponseDto(board);
} else {
throw new IllegalArgumentException("해당 사용자 혹은 관리자가 아니면 게시글을 수정할 수 없습니다!");
}
// Board에서 해당 값을 검증
public boolean isWriter(Long userId){
return this.user.isValidUserId(userId) || this.user.isAdmin();
}
// user에서 검증
public boolean isValidUserId(Long userId) {
return this.id.equals(userId);
}
public boolean isAdmin(){
return this.userRoleEnum.equals(UserRoleEnum.ADMIN);
}
이러한 방식으로 서비스 코드들에 존재하는 코드를 수정하여 가독성을 높이고 의존성을 낮추게 되었다.
- 시큐리티 - 기존의 오류 잡기
- 기존의 경우 requestMatcher().permitAll()을 하게 되면 해당 request안에 있는 url은 따로 스프링에서 제공하는 필터를 타지 않는 것으로 알고 있었다
- 다만 오늘 postman을 통해 signup을 실행한 결과 이 url을 가진 메서드를 통과하기에 해당 과정에서 의문을 가졌고 해당 과정을 debug를 찍으면서 과정을 찾아봤다
- 일단 permitAll()을 하면 인증/인가의 부분을 다 풀어주기에 바로 컨트롤러와 서비스가 연결되는 줄 알았다.
- 하지만 디버그를 찍으면서 확인한 결과 실제로는 코드상의 구조로 인해 통과가 되었다.
if (token != null) {
if (!jwtUtil.validateToken(token)) {
jwtExceptionHandler(response, "Token Error", HttpStatus.UNAUTHORIZED.value());
return;
}
Claims info = jwtUtil.getUserInfoFromToken(token);
setAuthentication(info.getSubject());
}else{
jwtExceptionHandler(response, "Token is null", HttpStatus.NOT_FOUND.value());
return;
}
filterChain.doFilter(request, response);
해당 필터단의 일부이다. 해당 필터에서 else의 return 값 같은 반환 코드가 작성이 되어있지 않았기에 해당 부분을 통과하고 넘어가던 것이었으며, 이에 따라 다른 부분에서 exception이 터지면 거기서 exception이 터지고 반환이 된 것이다.
그래서 해당 부분의 경우 token의 null값을 잡아주기 위해 return을 시켜주는 과정으로 나중에 null값의 경우를 생각했다.
또한 user의 url 요청을 올바르게 처리하기 위해 config에 해당 관련 코드를 넣어서 인증, 인가를 통과하는 방식을 선택했다.
@Bean
public WebSecurityCustomizer webSecurityCustomizer(){
return (web) -> web.ignoring()
.requestMatchers(PathRequest.toH2Console())
.requestMatchers("/user/**")
.requestMatchers(PathRequest.toStaticResources().atCommonLocations());
}
해당 코드를 보면 requestMatcher를 통해 해당 접근은 무시하는 방향으로 진행을 하였다.
'기록 > TIL' 카테고리의 다른 글
[TIL] Today I Lerned - 230109 (0) | 2023.01.09 |
---|---|
[TIL] Today I Lerned - 230106 (0) | 2023.01.06 |
[TIL] Today I Lerned - 230104 (0) | 2023.01.04 |
[TIL] Today I Lerned - 230103 (0) | 2023.01.03 |
[TIL] Today I Lerned - 230102 (0) | 2023.01.02 |