로그인/로그아웃
URL : 로그인 폼 작성하기
UserController
GET/POST 방식
/WEB-INF/views -> login.jsp 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<title>로그인</title>
</head>
<body>
<div class="container mt-3 text-center">
<div class="row mt-5">
<div class="col-12 text-danger">
<!-- 에러 메세지 -->
</div>
</div>
<form action="${pageContext.request.contextPath }/user/login" method="POST">
<h1 class="h3 mb-3 fw-normal">로그인 하세요</h1>
<div class="row mt-5">
<div class="col-12 text-danger">
${REDIRECT_ATTR.error }
</div>
</div>
<div class="form-floating">
<input type="text" class="form-control" name="username" id="username" value="${REDIRECT_ATTR.username }" placeholder="name@example.com" required>
<label for="username">Username</label>
</div>
<div class="form-floating mt-1">
<input type="password" class="form-control" name="password" id="password" value="" placeholder="Password" required>
<label for="password">Password</label>
</div>
<div class="mb-3">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="w-100 btn btn-lg btn-primary my-1" type="submit">로그인</button>
<a class="w-100 btn btn-lg btn-primary my-1" href="${pageContext.request.contextPath }/user/register">회원가입</a>
<p class="mt-2 mb-3 text-muted">© 2017–2022</p>
</form>
</div>
</body>
</html>

* UserController
package controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import command.Command;
import command.user.LoginCommand;
import command.user.RegisterCommand;
import common.C;
@WebServlet("/user/*")
public class UserController extends HttpServlet {
private static final long serialVersionUID = 1L;
public UserController() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doAction(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8"); // 한글 인코딩
doAction(request, response);
}
protected void doAction(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("UserController.actionDo() 호출");
String method = request.getMethod();
// URL로부터 URI, ContextPath, Command 분리
String uri = request.getRequestURI();
String conPath = request.getContextPath() + "/user";
String com = uri.substring(conPath.length());
// 테스트 출력
System.out.println("uri: " + uri);
System.out.println("conPath: " + conPath);
System.out.println("com: " + com);
Command command = null; // 어떠한 로직을 수행할지
String viewPage = null; // 어떠한 페이지(뷰)를 보여줄지
switch(com) {
case "/register":
if(method.equals("GET")) { // GET 방식의 경우 회원가입 폼
C.retrieveRedirectAttribute(request);
viewPage = "/user/register.jsp";
} else { // POST 의 경우
new RegisterCommand().execute(request, response);
// redirect 가 진행되면 이미 response 가 commit 됨.
// response 가 commit 되지 않은 경우만 jsp forward 진행
if(!response.isCommitted()) viewPage = "/user/registerOk.jsp";
}
break;
case "/login":
if(method.equals("GET")) { // GET 의 경우 로그인 폼
C.retrieveRedirectAttribute(request);
viewPage = "/user/login.jsp";
} else { // POST 의 경우 로그인 처리
new LoginCommand().execute(request, response);
// 로그인이 실패되면 위에서 redirect 되었을것이다
// 로그인이 성공하면
if(!response.isCommitted()) {
// 기본적으로 home 으로 redirect 한다
String redirectUrl = request.getContextPath() + "/home";
// 혹시 url prior (원래 가고자 했더 url) 존재했다면 url로 redirect 한다
String urlPrior = C.retrieveUrlPrior(request);
if(urlPrior != null) redirectUrl = urlPrior;
response.sendRedirect(redirectUrl);
}
}
break;
case "/logout":
if(method.equals("POST")) {
request.getSession().removeAttribute(C.PRINCIPAL);
// 혹은 session.invalidate();
response.sendRedirect(request.getContextPath() + "/home");
}
break;
case "/rejectAuth":
C.retrieveRedirectAttribute(request);
viewPage = "/common/rejectAuth.jsp";
break;
} // end switch
// 위에서 결정된 뷰 페이지(viewPage) 로 forward 해줌
if(viewPage != null) {
RequestDispatcher dispatcher
= request.getRequestDispatcher("/WEB-INF/views" + viewPage);
// request 에 담겨있는 Command 수행결과도 viewPage 에 전달되는 것이다
dispatcher.forward(request, response);
}
} // end doAction()
}
* LoginCommand
로그인 처리 -> command/LoginCommand
1. 검증
- 존재하지 않는 아이디(username) 의 경우
- 패스워드가 다른 경우
2. 검증 통과시 로그인 진행
- session 에 로그인한 사용자 정보 저장.
package command.user;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import command.Command;
import common.C;
import domain.UserDAO;
import domain.UserDTO;
public class LoginCommand implements Command {
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws IOException {
//입력한 값을 받아오기
String username = request.getParameter("username");
String password = request.getParameter("password");
String conPath = request.getContextPath();
// ※ 파라미터 유효성 검증 필요
username = username.trim().toUpperCase(); // 대문자로 비교
password = password.trim();
UserDTO dto = new UserDTO();
dto.setUsername(username);
try {
// 존재하지 않는 아이디(username) 의 경우
List<UserDTO> list = new UserDAO().selectByUsername(dto);
if(list.size() == 0) {
response.sendRedirect(conPath + "/user/login");
C.addRedirectAttribute(request, "error", "존재하지 않는 아이디(username)");
C.addRedirectAttribute(request, "username", username);
return; // 종료
}
// 패스워드가 다른 경우
dto = list.get(0);
if(!dto.getPassword().equals(password)) {
response.sendRedirect(conPath + "/user/login");
C.addRedirectAttribute(request, "error", "password 가 다릅니다");
C.addRedirectAttribute(request, "username", username);
return; // 종료
}
// 위 검증을 전부 통과하면 로그인 진행
// session 에 로그인한 사용자 정보 저장.
HttpSession session = request.getSession();
session.setAttribute(C.PRINCIPAL, dto); // 로그인한 회원의 정보를 세션에 저장
} catch(SQLException e) {
e.printStackTrace();
}
}
}
C.java에 가서 public static final String PRINCIPAL = "PRINCIPAL"; 만들기
-> 로그인 하면 저장되는 session name
로그인한 회원의 정보를 세션에 저장 C.PRINCIPAL
로그인 헤더 작성 header.jsp
/views/common/header.jsp 작성
home.jsp 에 include 하고 확인
로그인 여부, 권한여부에 따른 header 표시
header.jsp 수정
수동으로 로그아웃 해보면서, 샘플 계정들 하나하나 로그인 시키면서 결과 확인해보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<title>NavBar</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="javascript:void(0)">Security</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mynavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="mynavbar">
<ul class="navbar-nav me-auto">
<!-- 누구에게나 보이는 메뉴 -->
<li class="nav-item" TODO="">
<a class="nav-link" href="javascript:void(0)">Anonymous</a>
</li>
<c:if test="${not empty sessionScope.PRINCIPAL }">
<!-- 로그인한 사람에게만 보이는 메뉴 -->
<li class="nav-item" TODO="">
<a class="nav-link" href="javascript:void(0)">Authenticated</a>
</li>
</c:if>
<c:if test="${fn:contains(sessionScope.PRINCIPAL.authorities, 'ROLE_MEMBER') }">
<!-- 로그인한 사람중 ROLE_MEMBER 권한 있는 사람에게만 보이는 메뉴 -->
<li class="nav-item" TODO="">
<a class="nav-link" href="javascript:void(0)">Member</a>
</li>
</c:if>
<c:if test="${fn:contains(sessionScope.PRINCIPAL.authorities, 'ROLE_ADMIN') }">
<!-- 로그인한 사람중 ROLE_ADMIN 권한 있는 사람에게만 보이는 메뉴 -->
<li class="nav-item" TODO="">
<a class="nav-link" href="javascript:void(0)">Admin</a>
</li>
</c:if>
</ul>
<c:choose>
<c:when test="${empty sessionScope.PRINCIPAL }">
<!-- 로그인 안했을때는 로그인 form 보여주기 -->
<a class="btn btn-primary" type="submit" href="${pageContext.request.contextPath }/user/login">Login</a>
</c:when>
<c:otherwise>
<!-- 로그인 했을때는 username 과 로그아웃 form 보여주기 -->
<form action="${pageContext.request.contextPath }/user/logout" method="POST" TODO="">
<!--TODO : 로그아웃후 다시 돌아오기 -->
<span class="d-flex">
<span class="text-light p-2"><span TODO="">${sessionScope.PRINCIPAL.username }(${sessionScope.PRINCIPAL.name })</span> 님 환영합니다</span>
<span><button class="btn btn-danger" type="submit">Logout</button></span>
</span>
</form>
</c:otherwise>
</c:choose>
</div>
</div>
</nav>
<div class="container-fluid mt-3">
<c:choose>
<c:when test="${empty sessionScope.PRINCIPAL }">
<!-- 로그인 하지 않았을때 보여주는 화면 -->
<div TODO="" class="alert alert-warning alert-dismissible">
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
로그인하지 않은 상태입니다 <br>
</div>
</c:when>
<c:otherwise>
<!-- 로그인 했을때 보여주는 화면 -->
<div TODO="" class="alert alert-info alert-dismissible">
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
<c:out value="${sessionScope.PRINCIPAL }"/><br>
로그인 하셨습니다 <br>
</div>
</c:otherwise>
</c:choose>
</div>
</body>
</html>
sessionScope.PRINCIPAL 이 존재하면 로그인한 것
empty sessionScope.PRINCIPAL -> sessionScope.PRINCIPAL이 비어있으면 = 로그인하지 않으면
로그아웃 구현하기

'JSP' 카테고리의 다른 글
[JSP] Pagination (0) | 2022.04.11 |
---|---|
[JSP] Authentification - 회원제 게시판 (0) | 2022.04.10 |
[JSP] Authentication - 회원가입 (0) | 2022.04.07 |
[JSP] JSTL(JSP Standard Tag Library) (0) | 2022.04.06 |
[JSP] EL : Expression Language (0) | 2022.04.06 |