로그인을 하고 들어와야하는 사이트에 악의적으로 url만 입력하고 들어오는 경우가 있을수도 있다. 이것을 막기위해 우리는 필터,인터셉터를 사용할 예정이다.
로그인을 했는지 안했는지 체크하는 로직은 애플리케이션 모든 부분의 공통관심사(cross-cutting-concern)은 AOP 방식으로 해결할수 있지만 웹과 관련된공통관심사는 서블릿 or 스프링 인터셉터로 해결 하는것이 좋다.
웹과 관련된 공통 관심사를 처리할 때는 HTTP의 헤더나 URL의 정보들이 필요한데, 서블릿 필터나 스프링 인터셉터는 HttpServletRequest 를 제공함
요청 ->Was ->doFilter로 필터, 필터 통과한뒤에 -> 서블릿->컨트룰러
Http요청이오면 doFilter 가장먼저 호출
ServletRequest 는 HTTP 요청이 아닌 경우까지 고려해서 만든 인터페이스이다. HTTP를사용하면 다운 케스팅 하면 된다
요청마다 로그를 구분하기 위해 UUID 사용
chain.dofilter 부분을 호출해야 다음 필터로 넘어가고 ->서블릿 ->컨트룰러로 넘어감
이부분이 없으면 다음단계로 진행 x
인증 체크가 필요없는 부분은 따로 배열로 만들어 체크해준다.
로직은 어렵지 않다. 인증이 필요한 부분인지 체크 한뒤 필요한 부분이면 request에서 세션을 추출해 확인
HTTP 요청 ->WAS-> 필터 -> 서블릿 -> 스프링 인터셉터 -> 컨트롤러
스프링 인터셉터는 디스패처 서블릿과 컨트롤러 사이에서 컨트롤러 호출 직전에 호출 된다.
서블릿 URL 패턴과는 다르고, 매우 정밀하게 설정할 수 있다.
인터셉터도 필터처럼 여러개 사용 가능
HandlerInterceptor를 구현하면 됀다.
- 서블릿 -> 서블릿 필터제공
- 스프링MVC -> 인터셉터 제공
서블릿: 은 단순히 doFIlter 제공
서블릿: 단순히 request , response 만 제공
인터셉터는 호출전(preHandle), 호출후 (postHandle) , 요청완료 이후 (afterCompetion) 로 단계별로 분리
인터셉터는 어떤 컨트롤러( handler )가 호출되는지 호출 정보도 받을 수 있다. 그리고 어떤 modelAndView 가 반환되는지 응답 정보도 받을 수 있다.
-Prehanlder 에서 false값이 나오면 더 이상 진행 x
-afterCompletion 뷰가 렌더링 된 이후 호출 (무조건 실행됨, 예외가 발생해도 실행된다.)
preHandle 기존 서블릿 방식과 똑같이 랜덤값으로 로그 출력.
서블릿 필터의 경우 지역변수로 해결이 가능하지만, 스프링 인터셉터는 호출 시점이 완전히 분리되어 있다. 그래서 request.setAttribute로 aftercompletion 에서 사용할 값을 넣어어 보내줘야함.
예외가 발생해도 실행되는 afterCompleteion 에 종료로그를 만들어 준다.
인증체크는 prehandle만 필요한걸 알 수 있다. 다른건 구현 x, (interface-default라 기본 값은 있다.구현의무 x)
등록은 위에 인터셉터-등록 처럼 똑같이 해주면 됀다.
- 애노테이션이 있으면 직접 만든 ArgumentResolver 가 동작해서 자동으로 세션에 있는 로그인 회원을 찾아주고, 만약 세션에 없다면 null 을 반환하도록 개발해보자.
supportsParametr는 말그대로 서포트 즉 타입검사나 해당 파라미터에 우리가 만든 애노테이션이 있나 확인
supportsParameter 에서 true가 나오면 resolveArgement 실행
resolveArgument() 에서 눈여겨 봐야할 점은 webRequest 로 HttpServlet을 꺼내준다는점. 나머지 세션꺼내고 확인하는 로직은 같다.
등록은 어렵지 않다. addArgumentResolvers() 로 등록 해준다.
여러곳에서 공통적으로 쓰일 로직을 이런식으로 만들면 편리하다.