일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Could not find or load main class worker.org.gradle.process.internal.worker.GradleWorkerMain
- www-Authenticate
- 세션만들어보기
- hikaricp
- 프록시 캐시 서버
- max age
- must revalidate
- etag
- no cache
- 조건부요청
- HTTP상태코드
- 쿠키보안문제
- supportParameter
- 검증헤더
- 서블릿http세션
- http
- 캐시
- 양쪽 모두 값 설정
- 쿠키생명주기
- 인증체크
- gradle오류
- Expires
- Not Modified
- 세션타임아웃설정
- UrlResource
- 프록시객체
- HTTP API
- resolveArgument
- 300
- 서블릿필터
- Today
- Total
복습을 위한
서블릿 필터 본문
웹과 관련된 공통 관심사를 처리할 때 서블릿 필터를 사용한다.
예를 들어 로그인을 한 사용자만이 특정페이지에 접근을 할 수 있어야한다를 만족시키고싶을 때같은 경우이다.
필터 흐름
HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 컨트롤러
필터를 적용하면 필터가 호출 된 다음에 서블릿이 호출된다. 그래서 모든 고객의 요청 로그를 남기는 요구사항이 있다면 필터를 사용하면 된다. 참고로 필터는 특정 URL 패턴에 적용할 수 있다. /* 이라고 하면 모든 요청에 필터가 적용된다. 참고로 스프링을 사용하는 경우 여기서 말하는 서블릿은 스프링의 디스패처 서블릿으로 생각하면 된다.
필터체인
HTTP 요청 -> WAS -> 필터1 -> 필터2 -> 필터3 -> 서블릿 -> 컨트롤러
필터는 체인으로 구성되는데, 중간에 필터를 자유롭게 추가할 수 있다. 예를 들어서 로그를 남기는 필터를 먼저 적용하 고, 그 다음에 로그인 여부를 체크하는 필터를 만들 수 있다
필터인터페이스
public interface Filter {
public default void init(FilterConfig filterConfig) throws ServletException
{}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
public default void destroy() {}
}
init(): 필터 초기화 메서드, 서블릿 컨테이너가 생성될 때 호출된다.
doFilter(): 고객의 요청이 올 때 마다 해당 메서드가 호출된다. 필터의 로직을 구현하면 된다.
destroy(): 필터 종료 메서드, 서블릿 컨테이너가 종료될 때 호출된다.
default메소드가 있기 때문에 doFilter만 구현해도된다.
로그인 인증체크 필터를 구현해보자
@Slf4j
public class LoginCheckFilter implements Filter{
//로그인하지않아도 허용되는 페이지들
private static final String[] whitelist = {"/","/members/add", "/login","/logout","/css/*"};
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String requestURI = httpRequest.getRequestURI();
HttpServletResponse httpResponse =(HttpServletResponse) response;
try{
log.info("인증체크필터 시작{}", requestURI);
if(isLoginCheckPath(requestURI)){
log.info("인증체크 로직 실행{}",requestURI);
HttpSession session = httpRequest.getSession(false);
if(session ==null || session.getAttribute(SessionConst.LOGIN_MEMBER)==null){
log.info("미인증 사용자 요청{}", requestURI );
//로그인창으로 redirect
httpResponse.sendRedirect("/login?redirectURL="+requestURI);
//로그인화면 보내고 로그인 성공하면 기존 화면으로 돌아올 수 있게 배려하기위해 일단 현재페이지URL도 loginController로 같이 넘겨주자
return;//인증안되면 다음 필터나 컨트롤러로 못넘어감. finally문 실행되고 메소드 종료
}
}
chain.doFilter(request, response);//(whitelist이면) false면 다음 필터로 가든가 아님 서블릿으로 넘어감
}catch (Exception e){
throw e;
}finally {
log.info("인증 체크 필터 종료 {}", requestURI);
}
}
/*
* 화이트 리스트의 경우 인증 체크하지않는 메소드*/
private boolean isLoginCheckPath(String requestURI){
return !PatternMatchUtils.simpleMatch(whitelist,requestURI);
}//접근하는 사이트가 whitelist이면 false , whitelist가 아니면 필터체크해야하니 true반환
}
chain.doFilter(request, response); 이 부분이 가장 중요하다. 다음 필터가 있으면 필터를 호출하고, 필터가 없으면 서블릿을 호출한다. 만 약 이 로직을 호출하지 않으면 다음 단계로 진행되지 않는다.
간단히 말하자면 whitelist는 로그인하지않아도 접근할 수 있는 경로이다.
접근하려는 페이지가 whitelist에 해당되면 isLoginCheckPath에서 false를 반환받고 chain.doFilter를 통해 다음 필터나 컨트롤러로 넘어갈 수 있다.
해당되지않으면 세션을 통해 로그인 정보를 확인한다. 확인이 되면 특정페이지에 접근이 가능해지는 것이다. 확인되지않으면 로그인창으로 돌아간다. 이 경우 다음단계인 서블릿이 실행되지않아 Cotroller로 넘어갈 수가 없다.
리다이렉트 경로를 추가해준이유는 로그인이 성공했으면 기존에 머물던 페이지로 돌아갈 수 있게끔 해주기 위해서이다. 안그러면 홈화면으로 돌아갈 수 있으니깐 말이다.
참고로 ServletRequest request 는 HTTP 요청이 아닌 경우까지 고려해서 만든 인터페이스이다. HTTP를 사용하면 HttpServletRequest httpRequest = (HttpServletRequest) request; 와 같이 다운 케스팅 하면 된다.
WebConfig
@Bean
public FilterRegistrationBean loginCheckFilter() {
FilterRegistrationBean<Filter> filterRegistrationBean = new
FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new LoginCheckFilter());
filterRegistrationBean.setOrder(2);
filterRegistrationBean.addUrlPatterns("/*");
return filterRegistrationBean;
}
필터를 등록하는 방법은 여러가지가 있지만, 스프링 부트를 사용한다면 FilterRegistrationBean 을 사용해서 등록하면 된다
setFilter(new LogFilter()) : 등록할 필터를 지정한다.
setOrder(2) : 필터는 체인으로 동작한다. 따라서 순서가 필요하다. 낮을 수록 먼저 동작한다.
addUrlPatterns("/*") : 필터를 적용할 URL 패턴을 지정한다. 한번에 여러 패턴을 지정할 수 있다.
참고
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/dashboard
'SpringMVC' 카테고리의 다른 글
ArgumentResolver활용해보기 (1) | 2024.02.01 |
---|---|
스프링 인터셉터 (0) | 2024.01.31 |
세션타임아웃설정 (0) | 2024.01.31 |
서블릿http세션 (0) | 2024.01.30 |
쿠키보안문제와 세션 (0) | 2024.01.30 |