[ 스프링 시큐리티(Spring Security 작동 방식 ]
사용자가 /board 같은 특정 경로로 요청을 보내면 사용자의 요청이 애플리케이션의 핵심 로직을 처리하는 디스패처 서블릿(Dispatcher Servlet)에 들어오기도 전에, 필터가 그 요청을 가로채서 인증된 사용자인지를 먼저 확인한다. (리퀘스트에서 세션에 접근해서 사용자의 세션을 확인하는 방식) 사용자가 로그인을 통해 인증을 받으면, 서버는 그 사용자의 세션에 인증 정보를 저장. 그리고 사용자가 다른 요청을 보낼 때마다 필터는 이 세션 정보를 확인해서 사용자가 인증된 사용자인지를 판단한다. 만약 사용자가 인증되지 않았다면, 필터는 사용자를 로그인 페이지로 리다이렉트 하거나, 인증이 필요하다는 메시지를 보낸다. 사용자가 인증된 경우에만, 요청이 필터를 통과해서 디스패처 서블릿으로 이동하고, 이후에 처리되는 것! (시큐리티 사용했을 때, 메인 페이지부터 인증해야 들어갈 수 있게 모든 페이지를 막아놓은 걸 생각하면 될 듯)
필터에서 막아버리는 시큐리티. 필터는 진입 전만 가능!
[ 인터셉터(Interceptor) 작동 방식 ]
인터셉터는 필터(Filter)와 비슷한 역할을 하지만, 디스패처 서블릿(Dispatcher Servlet, DS) 이후에 위치하여 컨트롤러(Controller)로 가는 요청과 컨트롤러에서 뷰(View)로 응답을 보내기 전에 작업을 수행할 수 있다. 인터셉터를 설정하면, 특정 URL 패턴에 대해 요청이 들어왔을 때 특정 작업을 실행할 수 있다. ex. 1. /login으로 오는 요청이네? 그럼 인증 체크할 필요가 없지! -> /login은 그냥 통과 2. /board/** 경로로 들어오는 모든 요청에 대해 인증 체크하고 싶다. /board 경로에 해당하는 요청을 처리하기 전에 사용자가 로그인한 상태인지 확인하고, 로그인하지 않은 사용자는 로그인 페이지로 리다이렉트.
[ 인터셉터 사용 과정 ]
1. 인터셉터 생성 사용자의 요청을 처리하기 전, 후, 완료 후에 수행할 로직을 정의한 인터셉터 클래스를 생성 2. 인터셉터 등록 스프링 설정 파일이나 자바 설정 클래스에 인터셉터를 등록하고, 어떤 URL 패턴에 대해 이 인터셉터를 적용할지 지정 3. 인터셉터 동작 방식 (인터셉터는 주로 다음 세 가지 메서드를 통해 동작) 3-1. preHandle() 컨트롤러(핸들러) 메서드가 호출되기 전에 실행. 여기서 사용자 인증 체크 같은 작업을 수행 가능. 이 메서드에서 false를 반환하면 요청 처리가 중단된다. 3-2. postHandle() 컨트롤러 메서드가 실행된 후, 뷰가 렌더링되기 전에 호출된다. 이 시점에는 요청을 처리한 후의 추가 작업을 수행 가능 3-3. afterCompletion() 요청 처리가 완전히 끝난 후에 호출. 예외가 발생했는지 여부에 관계없이 실행 됨.
/board/1 같은 경로로 요청이 들어올 때 preHandle() 메서드에서 세션을 체크하여 사용자가 로그인한 상태인지 확인하고, 로그인하지 않았다면 로그인 페이지로 리다이렉트할 수 있다.
[ 인터셉터의 before 단계에서 세션 체크 ]
인터셉터에서 before 단계는 컨트롤러(또는 특정 핸들러)로 요청이 전달되기 바로 전에 실행 이 시점에서 사용자의 세션을 체크함으로써, 유효한 세션을 가진 사용자만이 서비스를 이용할 수 있도록 제한할 수 있다. 세션이 유효하지 않다고 판단될 경우, 즉시 처리를 중단하고, 로그인 페이지나 접근 권한이 없음을 알리는 페이지로 리다이렉트 after 단계는 요청이 처리된 후, 즉 컨트롤러의 로직이 실행된 후에 호출. 일반적으로 응답을 사용자에게 보내기 전에 후처리가 필요한 경우에 사용. 예를 들어, 로그 남기기, 실행 시간 계산, 공통 응답 데이터 추가 등의 작업이 여기에 해당
세션 체크를 before, after 선택해서 체크할 수 있다.
세션 체크와 같이 요청의 유효성을 판단하거나 사용자의 인증 상태를 확인해야 하는 로직은 before 단계에서 수행해야 한다!
시큐리티와 인터셉터는 실행 시점이 다르다는걸 꼭 기억하자!!
요즘은 대부분 다 시큐리티로 처리함. → 그러나 배울게 많고 어렵다!
[ 익셉션 핸들링(exception handling)이란? ]
익셉션 핸들링(exception handling)이란 프로그램 실행 중에 예외 상황이 발생했을 때, 이를 적절하게 처리하여 프로그램이 중단되지 않도록 하는 기술 만약, 데이터를 찾는 작업을 하다가 원하는 데이터가 없어서 NoResultException과 같은 예외가 발생했을 때, 스프링에서는 '익셉션 핸들러'를 사용한다. 즉, 예외가 발생하면 스프링이 자동으로 익셉션 핸들러를 찾아서 그곳으로 예외를 보내고, 익셉션 핸들러에서 예외를 처리한다. -> 각각의 부분에서 예외 처리 코드를 반복해서 작성할 필요가 없어지고, 예외 처리를 효율적으로 관리할 수 있다.
[ 그림으로 보는 익셉션 핸들러(Exception Handler, EH) ]
외부에서 요청이 들어오면, 쭉 통과통과해서 Repository까지 갔다. 그런데, 이 레파지토리에서 예외가 발생하게 된다면 (ex.NoResultException 같은) 예외를 throw (예외를 직접 처리하지 않고 호출한 애한테 try-catch를 위임) 하는데, 서비스나 컨트롤러에서 이 예외를 적절히 처리하지 않으면 예외는 계속 상위로 전달되어 디스패처 서블릿(DS)에 도달한다. 그리고 이 DS가 예외를 잡아내고, 등록된 예외 핸들러(Exception Handler)에게 처리를 위임! 즉, 오류 타입별로 익셉션 핸들러 메소드를 (스스로의 힘으로) 때려주는 것!! -> 개발자가 직접 구현한 익셉션 핸들러 메소드를 사용하여 다양한 타입의 예외를 처리할 수 있다!!
인터셉트(Interceptor)를 사용해서 인증 체크를 하고, 조건에 맞지 않을 경우 throw를 통해 요청 처리를 중단시키고 예외를 발생시킬 수 있으며, 이 경우 예외는 디스패처 서블릿으로 전달되고, 디스패처 서블릿은 등록된 익셉션 핸들러를 통해 이 예외를 처리함
익셉션 핸들러는 디스패처 서블렛이 호출하는 것이기 때문에 필터에서 THROW를 던져봤자 안 먹는다.
Share article