본문 바로가기

백엔드 개발/SpringMVC

Session 이용 실습(1)

<개요>

대다수의 웹페이지가 회원인지 아닌지에 따라 할 수 있는 행동들이 나뉜다.

우리가 만든 홈페이지에서는 클라이언트가 로그인 해야지만 게시판 페이지를 이용할 수 있다고 하자.

세션 객체 안에 id가 저장되어 있는지 아닌지를 통해 클라이언트가 로그인 했는지 안 했는지를 체크할 수 있다.

 

밑의 사진은 게시판에 들어가기 위한 로직을 나타낸 것이다.

1. BoardController와 boardList 만들기 

우리는 지금까지 로그인 화면(loginForm.jsp)과 로그인 후 들어올 수 있는 홈 화면(index.jsp) 2가지를 만들었다.

 

index.jsp를 살펴보면, 

<!--body의 내용-->
<div id="menu">
	<ul>
	    <li id="logo">fastcampus</li>
	    <li><a href="<c:url value='/'/>">Home</a></li>
	    <li><a href="<c:url value='/board/list'/>">Board</a></li>
	    <li><a href="<c:url value='/login/login'/>">login</a></li>    
	    <li><a href="<c:url value='/register/add'/>">Sign in</a></li>
	    <li><a href=""><i class="fas fa-search small"></i></a></li>
	</ul> 
</div>
<div style="text-align:center">
	<h1>This is HOME</h1>
	<h1>This is HOME</h1>
	<h1>This is HOME</h1>
</div>

위와 같이 list 태그와 a 태그로 게시판 화면, 로그인 화면, 회원가입 화면으로 갈 수 있는 버튼을 만들어 놓았다. 

우리는 아직 게시판 페이지와 그걸 통제할 컨트롤러를 안 만들었기 때문에 구현 해줘야 한다. 

위를 보면 Board를 클릭 했을 시, /board/list 라는 URL로 가게 되어있다. 조회만 하므로 GET 요청이다. 

해당 요청에 대응할 수 있는 Controller를 만들겠다. 

@Controller
@RequestMapping("/board")
public class BoardController {
	
    //1. /board/list mapping
	@GetMapping("/list")
	public String list(HttpServletRequest request) {
		
	//2. 로그인체크 - 안했으면 loginform으로 redirect, 
	//			했으면 게시판 JSP View 보여주기
		if(!loginCheck(request))
		{
			return "redirect:/login/login";  // 로그인을 안 했으면 로그인 화면으로 이동
		}
		
		
		return "boardList"; // 로그인 한 상태이면, 게시판 화면으로 이동
	}

	
	//3.  로그인 체크하는 매소드 구현
	// 	request에 적혀 있는 Session id를 통해 우리가 쓰는 세션 객체를 찾아 맵핑
	// 	그 세션 객체안에 id 값이 있는지 확인. 없으면 로그인 안한 것, 있으면 로그인 한 것.
	private boolean loginCheck(HttpServletRequest request) {
		// 세션을 얻어서
		HttpSession session = request.getSession();		
		// 세션에 id가 있는지 확인, 있으면 true를 반환
        	// getAtrribute("name")은 name의 value를 반환
		return session.getAttribute("id")!=null;
		
		
	//** 이 과정을 반환 값으로 한번에 나타내면 위처럼 된다.
//		if(session.getAttribute("id")!=null)
//			return true;
//		else
//			return false;

	}
}

 

로그인 한 상태이면 게시판 view를 보여줘야 하는데 아직 view를 안 만들었다. 만들어 보자.

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
    <title>fastcampus</title>
    <link rel="stylesheet" href="<c:url value='/css/menu.css'/>">
</head>
<body>
<div id="menu">
	<ul>
	    <li id="logo">fastcampus</li>
	    <li><a href="<c:url value='/'/>">Home</a></li>
	    <li><a href="<c:url value='/board/list'/>">Board</a></li>
	    <li><a href="<c:url value='/login/login'/>">login</a></li>    
	    <li><a href="<c:url value='/register/add'/>">Sign in</a></li>
	    <li><a href=""><i class="fas fa-search small"></i></a></li>
	</ul> 
</div><div style="text-align:center">
	<h1>This is BOARD</h1>
	<h1>This is BOARD</h1>
	<h1>This is BOARD</h1>
	<h1>This is BOARD</h1>
	<h1>This is BOARD</h1>
</div>
</body>
</html>

아직 뭐 내용이 없기 때문에 별 다를게 없다. 

여기서도 화면 상단의 목록은 여전히 작동해야해서 해당 내용을 똑같이 넣었다.

 

** 이렇게 구현하면 로그인을 안 했을 시 로그인 화면으로 돌아간다. 

하지만 로그인을 한 경우에도 로그인으로 돌아간다. 그 이유는 Login을 담당하는 Controller에서 로그인 시 해당 id를 세션에 저장하는 기능을 아직 넣지 않았기 때문이다.

밑에서 그것을 구현해보자.

2.Login 했을 시 Session에 Id 저장하는 기능 만들기

public class LoginController {
	
	//조회만 할시엔 로그인 입력창을 보여줘라
	@GetMapping("/login")
	public String loginform() {
		return "loginForm";
	}
	
	// 내용을 쓰고 로그인 요청(POST)를 했을시, 
	@PostMapping("/login")
    
    //** 세션 정보는 request 안에 있으므로 request도 받아야함.
	public String login(String id, String pwd, boolean rememberId, HttpServletRequest request ,HttpServletResponse response ) throws Exception {

		
		// 1. id와 pwd를 확인
		if(!loginCheck(id,pwd)) {
			String msg = URLEncoder.encode("id 혹은 패스워드가 올바르지 않습니다.", "utf-8");

			// 2-1 일치하지 않으면 loginform 으로 redirect, 스트링 쿼리로 화면에 보일 메세지도 같이 보냄.
			return "redirect:/login/login?msg="+msg;			
		}
		
		
		// 2-2 id와 pwd가 일치하면 세션 객체 얻어와서 그 안에 id를 저장.
		
		// 	세션 객체 얻어오기
		HttpSession session = request.getSession();
		
		//	세션 객체에 id를 저장
		session.setAttribute("id", id);
		
		
		if(rememberId) {
		// 1. 쿠키를 생성 
			Cookie cookie = new Cookie("id", id);
		// 2. 응답에 저장
			response.addCookie(cookie);
		}else {
		// 1. 쿠키를 삭제
			Cookie cookie = new Cookie("id", id );
			cookie.setMaxAge(0);
		// 2. 응답에 저장
			response.addCookie(cookie);
		}
		
		
		

		// 	3. 홈으로 이동	
			return "redirect:/";
	}

3. logout 할 수 있는 환경 만들고, 게시판 페이지나 홈 페이지에서 로그아웃 했을 때, 다시 로그인 안하면 게시판 이용 못하게 만들기.

위와 같이 만들면 위에 설계된 로직대로 작동한다. 

하지만, 내가 로그인을 한 상태인지 로그인을 안 한 상태인지 분간이 안간다. 

따라서 로그인을 했다면 그 후 홈페이지 상단 로그인 버튼이 로그아웃 버튼으로 바뀌고, 

로그아웃을 했다면 해당 버튼이 다시 로그아웃으로 돌아오면 좋겠다.

이를 위해서는 먼저 Controller에서 logout을 하려 할 때 대응할 수 있는 기능을 만들어야 한다. 

그 뒤에 해당 컨트롤러가 사용할 수 있는 View도 만들어야 한다. 

(1) Login Controller에 Logout 기능 만들기.

public class LoginController {
	
	//조회만 할시엔 로그인 입력창을 보여줘라
	@GetMapping("/login")
	public String loginform() {
		return "loginForm";
	}
	
	//로그아웃 시 세션 종료하고 홈 화면으로 URL 재조정
	@GetMapping("/logout")
	public String logout(HttpSession session) {
		// 1. 세션을 종료
		session.invalidate();
		// 2. 홈으로 이동
		return "redirect:/";
	}
	
    /...
}

(2) 이에 맞게 index.jsp, boardList.jsp 고치기

jsp 내에 변수를 만들어 해당 변수의 값은 삼항 연산자로, 세션에 id 있으면 login 글자 띄우기, 없으면 logout 글자 띄우기로 체인지 

<!-- 변수 만들고 삼항 연산자를 통해 세션에 id 있으면 login 없으면 logout 글자와 링크 띄우도록 만든다.
	 링크와 글자 각각 변수 하나씩 필요 -->
     
<c:set var = "loginOutLink"  value = "${sessionScope.id == null ? '/login/login' : '/login/logout'}"/>     
<c:set var = "loginOut" value = "${sessionScope.id == null ? 'Login' : 'Logout'}"/>


<!--... 리스트 태그에 로그인 목록 밑과 같이 바꾸기
		${변수이름}은 해당 변수의 값을 나타낸다.-->


	    <li><a href="<c:url value='${loginOutLink }'/>">${loginOut}</a></li>

index.jsp , boardlist.jsp 둘 다 이렇게 고치면 된다.

 

4. 직접 해보기

(1) boardlist.jsp 직접 바꾸기

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var = "loginLogOutLink" value = "${sessionScope.id = null? '/login/login':'/login/logout'}"/>
<c:set var = "loginOut" value = "${sessionScope.id = null? 'Login' : 'Logout'}"/>
    
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
    <title>fastcampus</title>
    <link rel="stylesheet" href="<c:url value='/css/menu.css'/>">
</head>
<body>
<div id="menu">
	<ul>
	    <li id="logo">fastcampus</li>
	    <li><a href="<c:url value='/'/>">Home</a></li>
	    <li><a href="<c:url value='/board/list'/>">Board</a></li>
	    <li><a href="<c:url value='${loginLogOutLink}'/>">${loginOut }</a></li>    
	    <li><a href="<c:url value='/register/add'/>">Sign in</a></li>
	    <li><a href=""><i class="fas fa-search small"></i></a></li>
	</ul> 
</div><div style="text-align:center">
	<h1>This is BOARD</h1>
	<h1>This is BOARD</h1>
	<h1>This is BOARD</h1>
	<h1>This is BOARD</h1>
	<h1>This is BOARD</h1>
</div>
</body>
</html>

${까지 치면 }가 저절로 쳐진다는 것을 인지하자. 링크 부분에 }}이렇게 두번 쳐져서 경로 오류가 나서 헤맸다.

(2) boardController 주석보고 써보기 

package com.fastcampus.ch2;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/board")
public class BoardController{
		//1. /board/list mapping
	@GetMapping("/list")
	public String list(HttpServletRequest request) {
		//2. 로그인체크 - 안했으면 로그인 화면으로 이동, 
		//			했으면 게시판 JSP View 보여주기
		if(!(logincheck(request))) {
			return "redirect:/login/login";
		}
		
		return "boardList";
	}


	//3.  로그인 체크하는 매소드 구현
	// 	request에 적혀 있는 Session id를 통해 우리가 쓰는 세션 객체를 찾아 맵핑
	// 	그 세션 객체안에 id 값이 있는지 확인. 없으면 로그인 안한 것, 있으면 로그인 한 것.
	private boolean logincheck(HttpServletRequest request) {
		// 세션을 얻어서
		HttpSession session = request.getSession();
		// 세션에 id가 있는지 확인, 있으면 true를 반환
		return session.getAttribute("id") != null;
	}
}	

		
		
	//** 이 과정을 반환 값으로 한번에 나타내면 위처럼 된다.
//		if(session.getAttribute("id")!=null)
//			return true;
//		else
//			return false;

redirect와 링크 사이에 띄어쓰기가 있어서는 아니된다. 

(3) Logout 부분 주석만 보고 스스로 추가

	//로그아웃 시 세션 종료하고 홈 화면으로 URL 재조정
	@GetMapping("/logout")
	public String logout(HttpSession session) {
		// 1. 세션을 종료
		session.invalidate();
		// 2. 홈으로 이동
		return "redirect:/";
	}

redirect를 붙이는 이유

이 명령어를 안 붙이면 컨트롤러는 "/"라는 jsp view를 찾는다. 

view가 아니라 해당 경로로 가라고 명령하고 싶으면 redirect: 를 붙여야 한다. 

'백엔드 개발 > SpringMVC' 카테고리의 다른 글

Spring에서 예외 처리하는 방법(1)  (0) 2023.03.11
세션(Session) 실습(2)  (0) 2023.03.10
Session- 이론  (0) 2023.03.09
쿠키란?  (0) 2023.03.05
Redirect와 Forward에 대하여  (0) 2023.03.04