Day95 - [Jquery]로그인 기능 구현(Session, Interceptor)

2021. 7. 1. 00:07Jquery

이번에는 어제 구현한 로그인에서, 세션을 만들었었죠?

 

만든 세션을 가지고, 세션의 유무를 판단해서 화면에 표시되는 내용 , 접근하지 못하는 페이지 등등 을 걸러 줄 겁니다.

 

이 때, Interceptor 에 대한 내용도 함께 알아보도록 합시다.

 

로그인 기능 구현

로그인을 완료한다면, 유저의 개인 페이지 등에 접근을 할 수 있습니다.

 

그런데, 현재 만든 페이지에는, 로그인을 하지 않아도 어떤 페이지든지 다 접근이 가능하니, 이를 불가능 하도록 만들어 줄 겁니다.

 

먼저, 어제 로그인을 처리할 때, 세션을 만들었습니다.

이제, 화면에서 "userVO" 라는 이름의 세션을 가지고 있지 않다면, 접근 불가 or 특정 기능을 사용 못하도록 만들어 줍시다.

 

게시판에서 로그인되어 있지 않다면, 글쓰기 버튼이 나타나지 않도록 해주려면 아래처럼 해주면 됩니다.

 

헤더 메뉴 에서도, 로그인을 했다면 로그아웃, 마이페이지가 나타나고, 로그인이 되어 있지 않으면, 로그인과 회원가입이 나타나게 하도록 아래처럼 사용 합니다.

<c:choose>
<c:when test="${sessionScope.userVO eq null }">
  <li><a href="${pageContext.request.contextPath }/user/userJoin"><span class="glyphicon glyphicon-user"></span>Join</a></li>
  <li><a href="${pageContext.request.contextPath }/user/userLogin"><span class="glyphicon glyphicon-log-in"></span>Login</a></li>
</c:when>
<c:otherwise>
  <li><a href="${pageContext.request.contextPath }/user/userMypage"><span class="glyphicon glyphicon-user"></span>MyPage</a></li>
  <li><a href="${pageContext.request.contextPath }/user/userLogout"><span class="glyphicon glyphicon-log-out"></span>Logout</a></li>
</c:otherwise>
</c:choose>

이런식으로 로그인의 유무에 따라 특정 기능을 사용하지 못하도록 할 수 있습니다.

 

그러면, 이제 특정 페이지를 접근 못하도록 하게 해주겠습니다.

 

로그인이 되어 있지 않다면, 게시판 글의 수정, 삭제, 내 회원정보 등의 페이지에 들어가지면 이상하겠죠?

 

이런 페이지를 막아 줄껀데요, 

 

각각의 페이지마다 들어가서, 세션의 유무를 판단해서 접근하지 못하도록 해주면 .....

 

이런 회원전용 페이지가 생길 때마다 추가될 때마다 변경될 때마다 코드를 추가, 수정, 삭제 를 해줘야 돼요 전부 일일히

 

그러면 너무 비효율적 으로 됩니다.

 

그래서 Interceptor 라는 개념이 등장하게 되는데요.

 

이는, 화면에서 "회원 전용 페이지 요청" 을 하면, 컨트롤러를 거치기 전에, 가로채서 session 을 가지고 있는지 검사를 하고, session 을 가지고 있다면, 원래대로 컨트롤러로 이동시켜주고, 아니라면 컨트롤러를 이동하지 않고, 끝내도록 합니다. ( 컨트롤러로 이동하면 페이지 이동, 컨트롤러를 이동 못하면, 경고창, 뒤로가기 )

 

이는 이미 만들어져 있는 기능이기 때문에 상속 받아서 사용하면 됩니다.

 

HandlerInterceptorAdapter 라는 클래스를 상속 받으면, 오버라이딩으로 "PreHandle" , "PostHandle" 을 사용할 수 있습니다.

"PreHandle" 은 컨트롤러를 타기 전에 가로채서 실행.

"PostHandle" 은 컨트롤러를 탄 후 뷰로 이동할 때 가로채서 실행.

 

여기서는 게시판의 수정, 삭제 등을 요청하게 되면, 컨트롤러를 거치기 전에 가로채서 처리해 줄 것이기 때문에, PreHandle 을 오버라이딩 합니다.

@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
//		화면에서 넘어오는 작성자명
		String writer = request.getParameter("writer");
		
//		로그인된 사용자가 가지고 있는 세션정보
		HttpSession session = request.getSession();
		UserVO vo = (UserVO)session.getAttribute("userVO");
		
//		System.out.println(vo);
//		System.out.println(writer); // 핸들러 등록 -> bean
		
		if( vo != null ) {
			if( writer != null ) {
				if(vo.getUserId().equals(writer) ) { // 세션에 저장된 id와 작성자가 동일하다면
					return true; // 컨트롤러 실행
				}
			}
		}
		
		response.setContentType("text/html; charset=utf-8"); 
		PrintWriter out = response.getWriter(); // 화면에 문자열 형태로 전당할 때 사용하는 out객체
		
		out.println("<script>");
		out.println("alert('권한이 없습니다.');");
		out.println("history.go(-1);");
		out.println("</script>");
		
		return false; // 컨트롤러 실행x
		
	}

위의 코드는 화면에서 수정, 삭제 등이 일어날 때, 글의 작성자 를 매개변수로 넘겨지도록 해서, 세션에 있는 로그인 정보와 비교를 하고, ID 와 작성자가 일치하면 실행되도록 하고, 아니라면 <script> 를 이용해서 경고창을 띄우고 뒤로가기를 수행하는 메서드 입니다.

 

이렇게, 인터셉터 를 만들어 주었다면, 이 인터셉터가 실행될 수 있도록 Bean 으로 등록 해주어야 합니다.

이렇게 설정파일에서 작성을 해주게 되면 실행했을 때, 위의 Path 경로를 요청하는 페이지는 컨트롤러를 거치기 전에 위에서 만든 인터셉터를 거치게 됩니다.

 

이번에는 컨트롤러를 타고 난 후 처리 "PostHandle" 을 사용해 봅시다.

 

사실 위에서 로그인을 하고 난 후에, 로그인에 성공하면 컨트롤러 에서 세션을 만들어 주었습니다. 하지만, 아래처럼 "PostHandle" 을 이용해서 로그인을 성공하면 세션을 만들어 줘도 됩니다.

 

-Intercepter-

 

-Controller-

"PostHandle" 은 컨트롤러를 수행한 후에 뷰 화면으로 이동할 때 가로채서 역할을 수행하기 때문에, 위처럼 만들어 주어도 됩니다.