스프링 부트에서 필터(Filter)는 클라이언트와 서버 간의 통신에서 요청과 응답을 가로채어 처리하는 역할을 수행합니다. 필터는 서블릿 컨테이너 내에서 작동하며, 클라이언트의 요청이 서블릿으로 전달되기 전이나 응답이 클라이언트에게 전송되기 전에 중간에서 작업을 수행할 수 있습니다.
@slf4j
로그 수행 작업을 하려면 해당 에노테이션을 사용
Filter Chain
필터체인은 필터는 우선 한개만 존재하는 것이 아니다. 여러개가 chain 형식으로 묶여서 처리가 가능하다
@Order
필터의 순서를 정함
필터의 기능 중 인증 및 인가 처리 필터 ▼
@Slf4j(topic = "AuthFilter")
@Component
@Order(2)
public class AuthFilter implements Filter {
// UserRepository, JwtUtil 해당 기능을 사용하기 위해 주입
private final UserRepository userRepository;
private final JwtUtil jwtUtil;
// 생성자
public AuthFilter(UserRepository userRepository, JwtUtil jwtUtil) {
this.userRepository = userRepository;
this.jwtUtil = jwtUtil;
}
//인터페이스 Filter에 doFilter메서드 오버라이드
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
// getRequestURI() url 정보를 가지고 와서 스트링 타입으로 url에 담음 (인가 처리)
String url = httpServletRequest.getRequestURI();
// 해당 URL들은 인증처리에서 제외 시키려고 if 문에 담음
if (StringUtils.hasText(url) &&
(url.startsWith("/api/user") || url.startsWith("/css") || url.startsWith("/js"))
) {
// 회원가입, 로그인 관련 API 는 인증 필요없이 요청 진행
chain.doFilter(request, response); // 다음 Filter 로 이동
} else {
// 나머지 API 요청은 인증 처리 진행
// httpServletRequest에서 쿠키 목록 가지고 와서 jwt에 저장된 쿠키 찾음
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")
);
//setAttribute메서드는 "user"로 키값을 하고 그에 해당하는 value user값을 가져온다
request.setAttribute("user", user);
// 다음 Filter 로 이동
chain.doFilter(request, response);
} else {
throw new IllegalArgumentException("Not Found Token");
}
}
}
}
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
캐스팅 하는 이유?
이 인터페이스는 HTTP요청 및 응답에 트고하된 메서드와 속성을 포함하지 않고 있음
HttpServletRequest 는 ServletRequest 하위 인터페이스로 HTTP프로토콜에 특화된 메서드와 속성을 제공함
예를 들어서 gerRequestURI() 메서드를 사용하여 현재 요청의 URI를 가져 올 수 있음
Filter에서는 주로 HTTP 요청과 응답에 대한 정보를 처리해야하는 경우가 많다.
그래서 HttpServletRequest 로 캐스팅해서 HTTP요청에 대한 정보에 접근 가능하려 한다.
요약하면
HttpServletRequest 로의 캐스팅은 Filter에서 http 요청에 접근하기 위해 ServletRequest를 http-specific인터페이스로 변환하는 역할을 한다. 이를 통해서 http요청의 url 및 기타 http 특정 정보를 필터에서 사용 할 수 있게 한다.
'TIL' 카테고리의 다른 글
+25 Spring Security : JWT로그인 (0) | 2023.07.09 |
---|---|
+24 Spring Security 프레임워크 (1) | 2023.07.08 |
+22 JWT 토큰기반 무엇일까? (0) | 2023.07.06 |
+21 Spring DATA JPA란 무엇?? (0) | 2023.07.05 |
+20 영속성 컨텍스트란? 영속성 컨텍스트의 기능 (0) | 2023.07.04 |