SMALL
Filter 란?
- Filter란 Web 애플리케이션에서 관리되는 영역으로 Client로 부터 오는 요청과 응답에 대해 최초/최종 단계의 위치이며 이를 통해 요청과 응답의 정보를 변경하거나 부가적인 기능을 추가할 수 있습니다.
- 주로 범용적으로 처리해야 하는 작업들, 예를들어 로깅 및 보안 처리에 활용합니다.
- 또한 인증, 인가와 관련된 로직들을 처리할 수도 있습니다.
- Filter를 사용하면 인증, 인가와 관련된 로직을 비즈니스 로직과 분리하여 관리할 수 있다는 장점이 있습니다.
Filter는 한 개만 존재하는 것이 아니라 이렇게 여러 개가 Chain 형식으로 묶여서 처리될 수 있습니다.
* Spring 에서 모든 호출은 DispatcherServlet 을 통과하게 되고 이후에 각 요청을 담당하는 Controller 로 분배
하지만 이전단계에서 Filter 를 먼저 하고 들어옴.
코드를 짜보자.
@Slf4j(topic = "LoggingFilter")
//@Component
@Order(1)
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 전처리
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String url = httpServletRequest.getRequestURI();
log.info(url);
chain.doFilter(request, response); // 다음 Filter 로 이동
// 후처리
log.info("비즈니스 로직 완료");
}
}
@Slf4j(topic = "AuthFilter")
@RequiredArgsConstructor
//@Component
@Order(2)
public class AuthFilter implements Filter {
private final UserRepository userRepository;
private final JwtUtil jwtUtil;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String url = httpServletRequest.getRequestURI();
if (StringUtils.hasText(url) &&
(url.startsWith("/api/user") || url.startsWith("/css") || url.startsWith("/js"))
) {
// 회원가입, 로그인 관련 API 는 인증 필요없이 요청 진행
chain.doFilter(request, response); // 다음 Filter 로 이동
} else {
// 나머지 API 요청은 인증 처리 진행
// 토큰 확인
String tokenValue = jwtUtil.getTokenFromRequest(httpServletRequest);
if (StringUtils.hasText(tokenValue)) { // 토큰이 존재하면 검증 시작
// JWT 토큰 substring
String token = jwtUtil.substringToken(tokenValue);
// 토큰 검증
if (!jwtUtil.validateToken(token)) {
throw new IllegalArgumentException("Token Error");
}
// 토큰에서 사용자 정보 가져오기
Claims info = jwtUtil.getUserInfoFromToken(token);
User user = userRepository.findByUsername(info.getSubject()).orElseThrow(() ->
new NullPointerException("Not Found User")
);
request.setAttribute("user", user);
chain.doFilter(request, response); // 다음 Filter 로 이동
} else {
throw new IllegalArgumentException("Not Found Token");
}
}
}
}
위와 같이 Filter 를 만들었고 어떤 Filter 부터 작동할건지는 @Order 어노테이션을 통해 정할수 있다.
@Order 란?
구성 요소의 순서를 결정하는 선택적 값 인수가 있습니다. 기본값은 Ordered.LOWEST_PRECEDENCE 입니다 . 이는 구성 요소가 정렬된 다른 모든 구성 요소 중에서 가장 낮은 우선 순위를 갖는다는 것을 나타낸다.
관련 문서 : https://www.baeldung.com/spring-order
반응형
LIST
'Spring' 카테고리의 다른 글
Spring interface 의존성 주입 (0) | 2023.07.31 |
---|---|
QueryDSL (1) (2) | 2023.07.10 |
Spring Security (3) (0) | 2023.06.26 |
JWT (0) | 2023.06.26 |
@Configuration 쓰고 안쓰고의 차이점 (0) | 2023.06.24 |