- Spring MVC 마스터하기 필터 12022년 06월 03일
- starryeye
- 작성자
- 2022.06.03.:10
이전 쿠키 세션 포스팅에서 문제점이 있다..
로그인을 하지 않은 상태에서 로그인을 해야만 접근 할 수 있도록 의도한 페이지의 URL을
주소창에 직접 타이핑하여 접근을 하면... 접근이 된다!
이러한 문제는.. 로그인 여부를 체크하지 않은 URL로 요청되는 모든 컨트롤러에 모두 해당된다.
공통 관심사로 해결해야한다.
-> 그렇지 않으면 모든 컨트롤러에 로그인 여부를 체크하는 로직을 넣어줘야하여 관리가 어려워진다.
-> 공통 관심사는 스프링의 AOP로 해결할 수 도 있지만, 웹과 관련된 공통 관심사를 처리 할 때는
이미 서블릿에서 제공하는 필터와 스프링에서 제공하고있는 인터셉터를 사용하는 것이 좋다.
<참고>
사실 무엇이 좋고 나쁘다는 없다.
스프링을 사용할 수 있을때는 인터셉터,
그렇지 않을 땐 Filter,
비즈니스 로직에서는 AOP를 사용하면 좋을 것으로 보인다.
위 이미지는 요청/응답의 순서도이다.
요청이 들어오면..
요청 -> WAS(서블릿 컨테이너) -> 필터 -> DispatcherServlet -> 인터셉터 -> 각 메서드 컨트롤러의 AOP(Proxy패턴) -> 컨트롤러
응답으로 나갈때는 요청 호출의 역행으로 return 된다.
컨트롤러 -> 각 메서드 컨트롤러의 AOP(Proxy패턴) -> 인터셉터 -> DispatcherServlet -> 필터 -> WAS -> 요청
필터 : 서블릿이 지원한다.
인터셉터 : 스프링이 지원한다.
서블릿 필터
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 : 필터 초기화 메서드, 서블릿 컨테이너가 생성될 때 호출 (default 키워드로 구현안해도됨)
doFilter : 요청할 때 마다 해당 메서드가 호출된다. 필터의 로직이 위치
-> doFilter에서 chain.doFilter(request, response)를 호출해야 한다.
-> 호출 해야.. 다음 필터나 dispatcherServlet으로 갈 수 있다.
-> 싱글톤 클래스이므로.. Stateless 하게 코드를 짜야한다. (왠만하면 doFilter 지역변수로 사용)
destroy : 필터 종료 메서드, 서블릿 컨테이너가 종료될 때 호출 (default 키워드로 구현안해도됨)
로그인 여부를 체크해야할 모든 페이지에 서블릿 필터를 이용하여 요청을 필터링 해보자
<요구사항>
필터를 이용하여 로그인이 되어있어야 들어갈 수있는 페이지와
로그인이 필요없는 페이지를 구분하자!
로그인이 필요한 페이지에서 로그인이 안되어있다면 로그인을 할 수 있는 페이지로 보내자!
Filter 인터페이스 구현
Filter 인터페이스를 상속받아 구현하였다.
PatternMatchUtils.simpleMatch 메서드를 활용하여 인증과 무관하게 항상 허용되는 URI 패턴을 구분한다.
(부정으로 return 하여 해당 메서드를 호출한 if 문은 인증여부 필터가 필요할때 true가 되도록한다.)
인증 여부 필터가 필요할 경우..
httpRequest.getSession(false) 메서드를 호출하여 세션을 얻는다. (생성 X)
세션이 없거나, 세션이 있어도 세션내에 로그인 속성이 없으면 미인증 사용자 이다.
-> httpResponse.sendRedirect() 메서드를 사용하여 로그인 페이지로 redirect 한다.
-> "/login?redirectURL=" + requestURI 로 로그인 페이지에서 로그인이 되면 원래 보려고 했던 페이지로 가도록 한다.
-> return 하여 더이상의 필터나 dispatcherServlet으로 진행하지 않고 여기서 끝낸다. (redirect가 응답)
인증 여부 필터가 필요 없는 페이지 이거나, 세션에 로그인 속성이 있다면...
chain.doFilter() 메서드를 호출하여 다음 필터나 dispatcherServlet 으로 간다.
서블릿 필터 등록
구현한 서블릿 필터(loginCheckFilter 클래스)를 스프링 빈으로 등록해보자..
(스프링 부트를 사용한다면 위와 같이 @Configration 를 사용한 클래스에서 가능)
(스프링이 알아서 등록해줌)
FilterRegistationBean의 메서드..
setFilter : 구현한 서블릿 필터를 등록
setOrder : 해당 필터 순서를 정해준다.
(예시에서는 2번째..)
addUrlPatterns : 해당 필터를 적용할 URL 패턴을 지정한다. (여러개 가능)
-> 위 예시(등록 과정)에서는 모든 요청에 해당 필터가 적용되도록 하였다.
-> 실제 필터에서 whitelist 로 인증 여부 필터가 필요한 경우와 아닌경우로 나누어진다. (좀 불편..)
<참고>
서블릿 필터 구현체에..
@ServletComponentScan @WebFilter(filterName = "logFilter", urlPatterns ="/*") 으로
필터 등록이 가능하지만.. 에노테이션에 SetOrder 요소가 없어서 필터 순서 조절이 안된다.
로그인 성공 시.. 처음 요청한 페이지로 다시 redirect 되는 부분 구현
@RequestParam 으로 redirectURL key를 받는다. (defaultValue 요소를 사용하여 없어도 동작되도록 한다.)
-> 없으면 홈화면
로그인이 성공한다면...
return "redirect:/" + redirectURL로 로그인 페이지로 리다이렉트 되기전 페이지로 돌아간다.
'Spring > MVC' 카테고리의 다른 글
Spring MVC 마스터하기 5 (0) 2022.06.04 Spring MVC 마스터하기 인터셉터 1 (0) 2022.06.04 Spring MVC 마스터하기 쿠키, 세션 4 (0) 2022.06.03 Spring MVC 마스터하기 쿠키, 세션 3 (0) 2022.05.29 Spring MVC 마스터하기 쿠키, 세션 2 (0) 2022.05.29 다음글이전글이전 글이 없습니다.댓글