<개요>
대다수의 웹페이지가 회원인지 아닌지에 따라 할 수 있는 행동들이 나뉜다.
우리가 만든 홈페이지에서는 클라이언트가 로그인 해야지만 게시판 페이지를 이용할 수 있다고 하자.
세션 객체 안에 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 |