Search

[스프링, 타임리프] 로그인 여부에 따른 헤더 로그인/로그아웃 버튼 변경

Last update: @3/19/2023

개요

로그인 여부에 따라 헤더 버튼이 아래처럼 달라져야 함
비 로그인 상태 - 로그인, 회원가입
로그인 상태 - 로그아웃, 회원 정보
스프링 부트 3.0부터 보안 상 이유로 타임리프에서 #session 객체를 사용할 수 없어지고, 필요할 경우 컨트롤러에서 model에 담아서 타임리프로 전달해야 함
하지만 이렇게 될 경우 컨트롤러마다 버튼을 보여줄 조건을 속성에 넣어줘야 함
찾아보니 이를 해결하기 위해 스프링 시큐리티를 많이 사용하는 것 같음
나는 스프링 인터셉터를 사용해서 구현하기로 함

스프링 인터셉터

인터셉터
public class LoginInterceptor implements HandlerInterceptor { @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { HttpSession session = request.getSession(false); if (session == null || session.getAttribute("loginUser") == null) { request.setAttribute("isLoggedIn", false); } else { request.setAttribute("isLoggedIn", true); } } }
Java
복사
세션을 뒤져서 로그인 정보 확인(getSession 시 false 옵션으로 불필요한 세션 생성 방지)
세션이 없음 - 비 로그인 사용자
세션이 있지만 로그인 정보(User)가 없음 - 비 로그인 사용자
세션이 있음 - 로그인 사용자
로그인 정보 유무에 따라 isLoggedIn 속성에 true 또는 false 지정
인터셉터 등록
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) .order(1) .addPathPatterns("/**"); } }
Java
복사
예시 편의상 모든 요청에 대해 지정했지만 excludePathPatterns로 비로그인/로그인 사용자가 공통으로 사용하는 페이지만 지정하는 것이 효율적
로그인 사용자 전용 페이지는 위 인터셉터보다 높은 order를 지정한 인터셉터를 등록해 사전에 차단하는 것이 좋음

뷰(타임리프)

<header class="border-bottom"> ... <a th:unless="${isLoggedIn}" href="/users/login">로그인</a> <a th:unless="${isLoggedIn}" href="/users/new">회원가입</a> <a th:if="${isLoggedIn}" href="/users/logout">로그아웃</a> <a th:if="${isLoggedIn}" th:href="|/users/${user.id}|">내 정보</a> ... </header>
HTML
복사
isLoggedIn 조건에 따라 한 쪽은 th:if, 한 쪽은 th:unless로 버튼을 배타적으로 생성

결과 화면

로그인 전
로그인 후