이번장은 interceptor를 이용하여 로그인 처리를 해보도록 하겠습니다.
인터셉터는 주로 컨트롤러 이벤트 호출전에 가로채서 어떠한 처리를 해주기 위해 사용되는 기능입니다.
만약 인터셉터를 사용하지 않고 일반적 로그인 체크를 코드마다 모두 작성한다고 가정해보도록 하겠습니다
위처럼 로그인이 필수인 컨트롤러를 작성할때 마다 로그인 체크 로직을 CTRL + C/V 해주어야 합니다.
코드도 길어지고 로그인 체크 일부가 변경되면 모두 변경해주어야 하는 번거로움이 있습니다.
이부분을 해결하기위해 별도로 로그인 체크유틸을 만들어서 사용하는 분들도 계시긴하지만
만약 유틸클래스명이나 사용하려는 메서드 일부가 변경이된다면?
일일이 모두 변경해주어야 하는 번거로움이 있습니다.
인터셉터를 만약에 정의하게 된다면?
위처럼 인터셉터를 거쳐서 통과시 컨트롤러 호출이 진행됩니다.
세션체크가 필요한 페이지는 XML 설정에 의해 정의해줌으로써
각 페이지마다 로그인 체크 해주는 코드를 작성해줄 필요가 없습니다.
그럼 로그인체크를 예를 들어서 인터셉터 설정을 잡아보도록 하겠습니다.
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/admin_main"/> <!-- 여러개 컨트롤러 추가 가능 --> <!-- <mvc:mapping path="/admin_write"/> <mvc:mapping path="/admin_update"/> <mvc:mapping path="/admin_delete"/> . . . --> <!-- 로그인체크 인터셉터 클래스 --> <bean class="com.spring.interceptor.Interceptor"/> </mvc:interceptor> </mvc:interceptors>
mvc-config.xml에 정의한 인터셉터 코드를 말씀드리자면
여러개의 인터셉터를 정의할수 있습니다.
mvc:interceptor 태그들을 mvc:interceptors내에 여러개 정의하여
컨트롤러 성향별로 인터셉터 여러개를 정의할 수 있습니다.
ex) 관리자 로그인, 사용자 로그인 등...
그리고 mvc:mapping 태그들을 mvc:interceptor 태그내에 여러개 정의하여
하나의 인터셉터로 여러개의 컨트롤러를 제어 할 수 있습니다.
ex) 관리자 로그인 후 글쓰기페이지,글수정페이지,삭제기능 등....
interceptors 태그 추가를 하였으면
"com.spring.interceptor" 패키지 생성 후에 "Interceptor" 클래스를 생성합니다.
그런 다음 코드를 작성해봅니다.
public class Interceptor extends HandlerInterceptorAdapter{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { try { //admin이라는 세션key를 가진 정보가 널일경우 로그인페이지로 이동 if(request.getSession().getAttribute("admin") == null ){ response.sendRedirect("/"); return false; } } catch (Exception e) { e.printStackTrace(); } //admin 세션key 존재시 main 페이지 이동 return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { super.postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { super.afterCompletion(request, response, handler, ex); } @Override public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { super.afterConcurrentHandlingStarted(request, response, handler); } }
위에 보시면 4가지의 인터셉터에 대한 오버라이드 속성이 존재합니다.
1. preHandle - controller 이벤트 호출전
2. postHandle - controller 호출 후 view 페이지 출력전
3. afterCompletion - controller + view 페이지 모두 출력 후
4. afterConcurrentHandlingStarted - 뭐 동시에 핸들링 해주는 메서드인대 정확히는 모르겠습니다.
위 4가지 방식 중 preHandle만 사용하였습니다.
/** * 가상의 로그인체크 컨트롤러 * @param request * @return */ @RequestMapping("/login") public String login(HttpServletRequest request){ String returnURL = ""; //웹페이지에서받은 아이디,패스워드 일치시 admin 세션key 생성 if(request.getParameter("id").equals("admin") && request.getParameter("password").equals("1234")) { Map<String, Object> map = new HashMap<String,Object>(); map.put("admin_id", "admin"); map.put("admin_name", "관리자"); request.getSession().setAttribute("admin", map); returnURL = "redirect:/admin_main"; //일치하지 않으면 로그인페이지 재이동 }else { returnURL = "redirect:/"; } return returnURL; } /** * 관리자메인 컨트롤러 * @return */ @RequestMapping("/admin_main") public String admin_main(){ return "admin_main"; }
2가지 컨트롤러를 생성하였는데
"/login" 컨트롤러는 임의로 로그인 체크를 위하여 생성한 컨트롤러이고
"/admin_main" 컨트롤러는 로그인 이후 세션이 생성된 시점에 접근이 가능한 관리자 메인 컨트롤러입니다.
각 컨트롤러에 return 페이지에 다음 코드를 작성해보겠습니다.
"/" 는 webapp/index.jsp를 의미하므로 index.jsp 파일의 body태그내에 다음과 같이 코드를 작성합니다.
<form action="/login" method="post"> <input type="text" name="id"/> <input type="password" name="password"/> <input type="submit" value="전송" /> </form>
마지막으로 "/admin_main" 컨트롤러 호출로부터
return 되는 jsp페이지를 "WEB-INF/view/" 경로에 추가 생성 한 다음
BDOY태그에 다음과 같이 코드작성을 합니다.
<h3>관리자메인페이지</h3> 관리자 아이디 : ${sessionScope.admin.admin_id }<br/> 관리자 이름: ${sessionScope.admin.admin_name }
위처럼 코드 작성을 해보았다면 실행을 해보도록 합니다.
세션유무로 인하여 페이지 접근권한 테스트를 해보기 위해서
최초로 URL에 바로 "/admin_main" 페이지를 접속해보도록 합니다.
실행결과 메인URL로 이동되어 로그인 페이지가 출력되었습니다.
세션이 존재 하지 않기때문에 로직에 따라서 자동으로 인터셉터에서 튕겨준 것입니다.
로그인테스트를 해보도록 하겠습니다.
admin/1234를 입력하여 전송버튼을 클릭해주도록 합니다.
그럼 위처럼 관리자 아이디와 이름을 확인할 수 있는
"/admin_main" 페이지로 성공적으로 이동이 되었습니다.
새로고침해도 역시 세션이 존재하고 있어서 페이지가 유지되고있습니다.
위처럼 인터셉터를 이용하여 로그인 세션체크를 해주시면 되겠습니다.
by 개발로짜
Spring3 + MyBatis 기본설정 + 연동테스트 후 쿼리로그 확인해보기 (8) | 2014.11.14 |
---|---|
Spring3 Maven을 이용하여 pom.xml에 oracle,mysql,mssql jdbc 라이브러리 등록하기 (0) | 2014.11.14 |
Spring3 RedirectAttributes 사용한 redirect POST 전송법 (0) | 2014.11.11 |
Spring3 Pathvariable 어노테이션을 이용하여 PARAMETER를 URL처럼 받아보기 (0) | 2014.11.11 |
Spring3 jackson JSON 라이브러리 + ResponseBody 이용하여 JSON 파싱하기 (0) | 2014.11.10 |