728x90

상단 메뉴의 로그인, 회원가입, 회원수정, 로그아웃 총 네 메뉴 중 로그인 했을 때와 안 했을 때로 나눠 두 개의 메뉴씩 나오도록 해보자. 로그인이 됐다면 회원수정과 로그아웃만 보이도록, 안 됐다면 로그인과 회원가입만 보이도록 할 것이다.

우선 상단 메뉴는 interceptor를 통해 관리가 된다. 이 인터셉터에 loginUserBean 객체를 주입받아 이 bean객체가 login된 상태인지 아닌지를 판별하면 된다.

public class TopMenuInterceptor implements HandlerInterceptor{

	private TopMenuService topMenuService;
	private UserBean loginUserBean;
	
	public TopMenuInterceptor(TopMenuService topMenuService, UserBean loginUserBean) {
		this.topMenuService = topMenuService;
		this.loginUserBean = loginUserBean;
	}
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		List<BoardInfoBean> list = topMenuService.getTopMenuList();
		request.setAttribute("topMenuList", list);
		request.setAttribute("loginUserBean", loginUserBean);
		return true;
	}
}

이 인터셉터를 다시 ServletAppContext에 등록하자.

	@Resource(name="loginUserBean")
	private UserBean loginUserBean;

...중략...

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		WebMvcConfigurer.super.addInterceptors(registry);
		
		TopMenuInterceptor topMenuInterceptor = new TopMenuInterceptor(topMenuService, loginUserBean);
		
		InterceptorRegistration reg1 = registry.addInterceptor(topMenuInterceptor);
		reg1.addPathPatterns("/**");
	}

이제 top_menu.jsp를 수정한다. 기존의 ul태그를 통해 나열해 놓은 메뉴를, c tag를 이용해 로그인 된 상태와 아닌 상태로 나눠 보여주면 된다.

		<ul class="navbar-nav ml-auto">
			<c:choose>
				<c:when test="${loginUserBean.isLogin() == true}">
					<li class="nav-item">
						<a href="${root}user/update" class="nav-link">회원수정</a>
					</li>
					<li class="nav-item">
						<a href="${root}user/logout" class="nav-link">로그아웃</a>
					</li>
				</c:when>
				<c:otherwise>
					<li class="nav-item">
						<a href="${root}user/login" class="nav-link">로그인</a>
					</li>
					<li class="nav-item">
						<a href="${root}user/signIn"class="nav-link">회원가입</a>
					</li>
				</c:otherwise>
			</c:choose>
		</ul>

로그인 되기 전, 메뉴
로그인 된 후 메뉴

로그아웃 기능은 컨트롤러에서 logout될 때 loginUserBean의 login여부 값을 false로 바꿔주기만 하면 된다.

	@GetMapping("user/logout")
	public String logout() {
		loginUserBean.setLogin(false);
		return "user/logout";
	}

이렇게 메뉴를 숨겨놓아도 url에 직접 쳐서 접근하는 경우가 있을 수 있다.

따라서 interceptor를 통해 아예 접근을 못하도록 하자.

CheckLoginInterceptor이라는 인터셉터를 새로 생성한다.

public class CheckLoginInterceptor implements HandlerInterceptor{

	private UserBean loginUserBean;
	
	public CheckLoginInterceptor(UserBean loginUserBean) {
		this.loginUserBean = loginUserBean;
	}
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		if(loginUserBean.isLogin()==false) {
			String contextPath = request.getContextPath();
			response.sendRedirect(contextPath + "/user/not_login");
			return false;
		}
		return true;
	}
}

loginUserBean을 생성자를 통해 받아서 로그인 여부를 판단한다.

public class CheckLoginInterceptor implements HandlerInterceptor{

	private UserBean loginUserBean;
	
	public CheckLoginInterceptor(UserBean loginUserBean) {
		this.loginUserBean = loginUserBean;
	}
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		if(loginUserBean.isLogin()==false) {
			String contextPath = request.getContextPath();
			response.sendRedirect(contextPath + "/user/not_login");
			return false;
		}
		return true;
	}
}

ServletAppContext에 이 인터셉터를 등록한다.

addInterceptor에 아래 코드를 추가한다.

CheckLoginInterceptor checkLoginInterceptor = new CheckLoginInterceptor(loginUserBean);
InterceptorRegistration reg2 = registry.addInterceptor(checkLoginInterceptor);
reg2.addPathPatterns("/user/modify", "/user/logout", "/board/**");
reg2.excludePathPatterns("/board/main");

not_login.jsp까지 만들고 controller로 매핑하면 제대로 동작함을 알 수 있다.

728x90

+ Recent posts