스프링수업 23일차

하파타카·2022년 4월 26일
0

SpringBoot수업

목록 보기
23/23

한 일

로그인

  • 인터셉터 사용
  • 로그인 유지
  • 로그아웃 기능 추가
  • 사이드 메뉴바

로그인 (2)

인터셉터를 이용한 로그인 관리.
시큐리티사용시 사용자 유지등을 직접 작성하지 않아도 됨.

인터셉터 사용

- LoginCheckInterceptor -

// 새 인터셉터 클래스를 만들어 인터페이스 HandlerInterceptor를 구현하여 인터셉터 만들기
// 로그인 후 컨트롤러를 거치는 페이지로 이동 시 계속해서 인증된 상태인지 확인
public class LoginCheckInterceptor implements HandlerInterceptor {

	// preHandle메서드: 컨트롤러에 가기 전 Interceptor에서 캐치하여 작업수행
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		HttpSession session = request.getSession();	// 세션 불러오기
		User user = (User) session.getAttribute("user");
		if (user == null) {
			// 로그인인증이 안된상태 => 로그인 화면으로 이동
			String url = session.getServletContext().getContextPath() + "/login";
			response.sendRedirect(url);
			System.out.println("LoginInterceptor # preHandle() : 로그인 인증안됨");
			return false;
		}
		
		// 인터셉터 메서드에서 리턴이 true이면 통과, false이면 차단
		System.out.println("LoginInterceptor # preHandle() : 인증됨");
		return true;
	}
}

핸들러 인터셉터를 구현한 클래스를 만듦.
session.getServletContext().getContextPath(): 현재 프로젝트의 주소(localhost:8080)에 /login 을 붙여 로그인 화면으로 이동시킴
if문에 걸리지 않으면 조건을 통과한 셈이므로 통과코드를 굳이 else문 아래에 작성할 필요는 없음.

- WebConfig -
모든 페이지에 적용시킬 예정이므로 bbs패키지 아래의 메인클래스와 함께 위치시킴.

@Configuration
public class WebConfig implements WebMvcConfigurer {
	
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 인터셉터를 추가하는 메서드
		registry
			.addInterceptor(new LoginCheckInterceptor())	// 앞서 구현한 클래스를 사용
			.addPathPatterns("/board/**") 		// 인터셉터를 적용할 컨트롤러 주소 (/board로 시작하는 모든 주소)
			.excludePathPatterns("/board/list", "/board/get");		// 적용안할 주소(로그인 안해도 게시판 조회는 가능하도록)
	}
}

WebMvcConfigurer인터페이스의 기능을 구현하여 사용.
/board 페이지에 접근할때 로그인인증여부를 체크하여 권한을 주되, 예외패턴을 두어 게시글을 조회하는 기능(리스트 조회, 단일 조회)은 인증여부와 관계없이 모두 가능하도록 함.


로그인 인증이 안된 상태로 게시글 수정, 삭제 기능 사용 시 지정해둔 문구가 콘솔에 출력되며 로그인화면으로 이동함.


로그인 유지

전체 컨트롤러에 적용시킬 Common클래스 생성

- Common -

@ControllerAdvice		// 모든 컨트롤러에 적용
public class Common {

	@ModelAttribute		// 모든 컨틀로러의 모델에 추가
	public void sharedData(Model model, HttpSession session) {
		// 세션에 인증된 유저가 있으면 유저이름을 모든 페이지에 전달
		User user = (User) session.getAttribute("user");
		if (user != null) {
			model.addAttribute("userName", user.getName());		// 유저객체가 있으면 username을 저장
		}
	}
}

@ControllerAdvice
@ModelAttribute

@ControllerAdvice, @ExceptionHandler를 이용한 예외처리

로그아웃 기능 추가

- LoginController -

@GetMapping("/logout")
public String getLogout(HttpSession session) {
	session.invalidate();	// 모든 세션 삭제
	// session.removeAttribute("user");	// 로그아웃 시 세션의 user객체 제거
    attr.addFlashAttribute("message", "Logout됨!");
	return "redirect:/login";
}

removeAttribute()은 세션의 특정 값을 삭제
invalidate()는 세션과 세션에 저장된 값 모두를 삭제

- nav.html -
로그인 인증이 되었을땐 로그아웃버튼을, 인증이 안되었을땐 로그인 버튼을 활성화

<ul class="ms-auto navbar-nav justify-content-end">
  <li class="nav-item d-flex align-items-center" th:if="${userName != null}">
    <form th:action="@{/logout}" method="get">
      <span th:text="${'😆 안녕하세요!, ' + userName}"></span>
      <button type="submit" class="badge bg-gradient-warning ms-3">로그아웃</button>
    </form>
  </li>
  <li class="nav-item d-flex align-items-center" th:if="${userName == null}">
    <a th:href="@{/login}" class="nav-link text-body font-weight-bold px-0">
      <i class="fa fa-user me-sm-1"></i>
      <span class="d-sm-inline d-none">로그인</span>
    </a>
  </li>

사이드 메뉴바

- aside.html -

<li class="nav-item" th:if="${userName}">
  <a class="nav-link text-white" th:href="@{/profile}">
    <div class="text-white text-center me-2 d-flex align-items-center justify-content-center">
      <i class="material-icons opacity-10">person</i>
    </div>
    <span class="nav-link-text ms-1">프로파일</span>
  </a>
</li>
<li class="nav-item" th:if="${userName == null}">
  <a class="nav-link text-white" th:href="@{/login}">
    <div class="text-white text-center me-2 d-flex align-items-center justify-content-center">
      <i class="material-icons opacity-10">login</i>
    </div>
    <span class="nav-link-text ms-1">로그인</span>
  </a>
</li>
<li class="nav-item" th:if="${userName}">
  <a class="nav-link text-white" th:href="@{/logout}">
    <div class="text-white text-center me-2 d-flex align-items-center justify-content-center">
      <i class="material-icons opacity-10">logout</i>
    </div>
    <span class="nav-link-text ms-1">로그아웃</span>
  </a>
</li>
<li class="nav-item" th:if="${userName == null}">
  <a class="nav-link text-white" th:href="@{/register}">
    <div class="text-white text-center me-2 d-flex align-items-center justify-content-center">
      <i class="material-icons opacity-10">assignment</i>
    </div>
    <span class="nav-link-text ms-1">가입하기</span>
  </a>
</li>

로그인o => 프로파일, 로그아웃 활성화
로그인x => 로그인, 가입하기 활성화

로그인인증이 안됐을때를 선택하려면 th:if="${userName == null}"를 써야함.
th:if="${!userName}"사용 시 에러발생

profile
천 리 길도 가나다라부터

0개의 댓글

관련 채용 정보