SPRING MVC - Filter, Interceptor (로그인 관련 권한 처리)

Sungjin·2021년 8월 2일
0

Spring

목록 보기
10/23
post-thumbnail

Servlet Filter 보다는 Spring Interceptor에 무게를 더 두겠습니다!

상황 가정

  • 특정한 페이지 말고는 로그인을 한 사용자만 페이지를 볼 수 있는 권한이 있다고 가정
    • 생각 가능한 시나리오
      • 컨트롤러들 마다 로그인 여부를 체크 : 굉장히 번거롭고, 로직을 수정해야할 일이 있으면 다 수정해야하는 번거로움 ( 공통적으로 처리해 줄 수 있는 기능이 있었으면 좋겠다!)
  • 해결 방법
    권한 처리와 관련된 공통 관심사를 filter 및 Interceptor를 활용하여 처리가 가능 !

Servlet Filter

  • 스프링 내에서의 필터 흐름
    1. Client의 요청
    2. Was
    3. Pre Filter (Filter는 chain으로 구성되므로 chain으로 이루어진 filter들이 모두 실행 됨)
    4. DispatcherServlet
    5. Controller Response
    6. DispatcherServlet
    7. Post Filter (Pre Filter 가 실행됐던 순서 반대 방향으로 실행됨)
    8. Was
    9. Client에게 response
  • Filter를 로그인 관련 권한 처리에 쓸 수 있는 이유
    • 특정 URl에 Filter를 걸 수 있음
      • 즉, 어느 곳에서는 filter를 걸고
      • 어느 곳에서는 안 걸수 있음
        이러한 이유로 권한 처리에서 생각해보면 index 페이지나, 로그인 페이지에는 filter를 걸지 않아 사용자들이 접근 가능하도록 설정할 수 있고 그 외에 모든 로그인이 필요한 곳은 filter를 걸어 인증이 안된 사용자는 접근이 불가능하도록 설정 가능!

filter의 흐름 과정을 보면 Controller에 가기 전에 이미 filter를 처리할 수 있으므로 번거롭게 controller마다 로직을 추가 안해도 되고 공통 관심사를 처리할 수 있습니다!
filter만으로도 충분히 훌륭하지만 filter개발 시 로직이 수행된 뒤에 filter를 chain으로 이어줘야한다는 번거로움이 있습니다. chain으로 이어주지 않으면 web app에 오류를 끼칠 수도 있죠.
그래서 스프링은 인터셉터라는 강력한 기능을 도입했습니다!

Spring Interceptor

  • Spring Interceptor의 흐름
    1. Client의 요청
    2. Was
    3. Pre Filter (Filter는 chain으로 구성되므로 chain으로 이루어진 filter들이 모두 실행 됨)
    4. DispatcherServlet
    5. Spring Interceptor (Pre Handle 적절하지 않은 요청이라 판단 되면 Controller를 호출하지 않음. 로그인 여부를 판단 가능!)
    6. Controller Response
    7. Spring Interceptor (Post Handle)
    8. DispatcherServlet
    9. Post Filter (Pre Filter 가 실행됐던 순서 반대 방향으로 실행됨)
    10. Was
    11. Client에게 response
      요청이 완료된 이후(View가 render)에는 Interceptor에서 afterCompletion 호출
    • controller에서 예외가 발생하게 되면
      1. post filter는 실행되지 않음
      2. after completion은 호출 (예외를 받아서 어떤 예외인지 확인 가능)

Spring Interceptor는 Spring Mvc에서 특화된 기능을 제공.. filter보다 더욱 편리할 수 있다

CODE를 봅시다!
처리 방법 : session이 존재하지 않다거나 session의 value가 존재하지 않다면 로그인된 상태라 보지 않을 것임!
로그인 처리과정은 이미 개발 완료된 상태라고 전제를 깔고 가겠습니다

LoginInterceptor

public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        HttpSession session = request.getSession();
        if(session==null || session.getAttribute("loginMember")==null){
        	response.sendRedirect("/login")
            return false;
        }

        return true;
    }
}

return true : 정상 호출, 다음 인터셉터나 controller가 호출됨.
return false : 적절하지 않은 요청. 다음 인터셉터나 controlelr 호출 안됨. 즉, 로그인이 안된 상황이라 볼 수 있음.
response.sendRedirect("/login")을 줌으로서 다시 로그인을 하도록 요청을 하게 됨.

WebConfig
스프링 Bean에 인터셉터를 추가 해주기 위해 WebMvcConfigurer를 implements 해줘야함.

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        
        registry.addInterceptor(new LoginInterceptor())
                .order(1)
                .addPathPatterns("/**")
                .excludePathPatterns("/","/members/add","/login","/logout","/css/**","/*.ico","/error");
    }

}

인터셉터를 스프링에 등록해 주면 됩니다!
코드를 설명하자면

"/","/members/add","/login","/logout","/css/**","/*.ico","/error" 

이 경로들을 제외하고는 모든 경로에 로그인 인증을 한다고 보시면 됩니다!

이상으로 포스팅을 마치겠습니다. 감사합니다 :)

이 글은 인프런 김영한님의 '스프링 MVC 2편 - 백엔드 웹 개발 핵심 기술'을 수강하고 작성합니다.
출처:https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/dashboard

profile
WEB STUDY & etc.. HELLO!

0개의 댓글