웹 애플리케이션에서 사용자 세션 만료 시 로그인 페이지로 강제 이동시키는 경우가 있다.
만약 ajax를 이용하여 서버와의 비동기 방식으로 통신하는 경우 사용자 세션이 만료되어 있다면 이를 어떻게 처리해야 할까?
스프링 시큐리티에서 커스텀 필터를 등록하여 사용자 세션 만료에 대한 exception을 catch한 후 예외 처리 하는 방법으로 ajax 통신에
대한 세션 타임 아웃 체크가 가능하다.
security-context.xml
<security:http> <!-- check session time out with ajax --> <security:custom-filter after="EXCEPTION_TRANSLATION_FILTER" ref="ajaxSessionTimeoutFilter"/> </security:http> <bean id="ajaxSessionTimeoutFilter" class="com.kyu.svc.common.filter.AjaxSessionTimeoutFilter"> <property name="ajaxHeader" value="AJAX" /> </bean>
client에서의 request 요청 시 header name 중 AJAX가 있는지 여부를 체크하기 위해서 ajaxHeader property 세팅
AjaxSessionTimeoutFilter.java
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; if (isAjaxRequest(req)) { try { chain.doFilter(req, res); } catch (AccessDeniedException e) { res.sendError(HttpServletResponse.SC_FORBIDDEN); } catch (AuthenticationException e) { res.sendError(HttpServletResponse.SC_UNAUTHORIZED); } } else { chain.doFilter(req, res); } } private boolean isAjaxRequest(HttpServletRequest req) { return req.getHeader(ajaxHeader) != null && req.getHeader(ajaxHeader).equals(Boolean.TRUE.toString()); }
로그인 된 사용자의 세션이 만료되면 spring security에서는 AccessDeniedException 예외를 발생시키고, AjaxSessionTimeoutFilter가
이를 catch하여 response로 에러 코드 403을 return한다.
jsp
$('#start').click(function() { $.ajax({ type : "GET", url : "${contextPath}/test/progressbar.json", dataType : "json", success : function(response) { alert(response.result); } }); });
jquery-common.js
(function($) { $.ajaxSetup({ beforeSend: function(xhr) { xhr.setRequestHeader("AJAX", true); }, error: function(xhr, status, err) { if (xhr.status == 401) { alert("401"); } else if (xhr.status == 403) { alert("403"); } else { alert("예외가 발생했습니다. 관리자에게 문의하세요."); } } }); })(jQuery);
모든 ajax 요청 전 beforeSend 함수가 호출되고, request 헤더에 AJAX를 세팅해 준다.
ajax 요청 후 사용자 세션이 만료되어 있다면, HTTP status 403을 return하게 되고, client는 이를 받아
로그인 페이지로 이동시키면 되는 것이다.
$.ajaxSetup의 error function에서 모든 ajax 요청에 대한 error를 처리하기 때문에 해당 코드를 외부 js로
분리한 후 공통 js로 사용한다면 중복 코드 없이 ajax session timeout 체크가 가능할 것이다.