MyBatis + MVC 실습 (4) : 로그인/로그아웃

회원가입 기능을 만들었으니...

이제 아래와 같은 로그인 모달을 띄워서 로그인 처리를 해 보자!

 

 

 

로그인 처리는 어떻게 해야 하는가?

지금까지처럼 request에 로그인 정보를 저장하면,

사용자가 페이지를 이동할 때마다 로그인 정보를 request 에 담아 보내줘야 하기 때문에 매우 비효율적이다.

따라서 사용자가 로그인한 상태인지 아닌지에 대한 정보는 session에 저장한다.

세션은 서버에 저장되기 때문에 사용자가 로그아웃을 하거나 브라우저를 종료하기 전까지는 이 정보가 유지된다!

 

 

또한 미로그인/로그인 상태에 따라 로그인 아이콘을 변경하고,

일반 회원이냐 관리자 회원이냐에 따라 보이는 메뉴의 종류를 달리 할 것이다.

 

 

가보자고~

 

 

 

로그인 모달 띄우기 / 로그아웃 처리하기

 

ajax 팝업 라이브러리 중 하나인 shadow-box를 이용해서, 

메인 페이지에서 로그인 아이콘을 누르면 팝업이 뜨도록 처리할 것이다.

로그아웃은 간단하게 session에 저장된 정보를 삭제하면 된다.

 

 

main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Gravity</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link href="../layout/styles/layout.css" rel="stylesheet" type="text/css" media="all">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<style type="text/css">
@font-face {
    font-family: 'NeoDunggeunmo';
    src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2001@1.3/NeoDunggeunmo.woff') format('woff');
    font-weight: normal;
    font-style: normal;
}
</style>
<link rel="stylesheet" href="../member/shadow/css/shadowbox.css">
<script type="text/javascript" src="../member/shadow/js/shadowbox.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery.js"></script>

<script type="text/javascript">
Shadowbox.init({
  players:['iframe']
})
$(function(){
  $('.images').css("cursor","pointer")
  $('#logImg').click(function(){
    Shadowbox.open({
      content:'../member/login.do',
      player:'iframe',
      title:'Login',
      width:480,
      height:260
    })
  })
  $('#logoutImg').click(function(){
    location.href="../member/logout.do";
  })
})
</script>
</head>
<body id="top" style="font-family:'NeoDunggeunmo'">
  <jsp:include page="header.jsp"></jsp:include>
  <%-- <jsp:include page="home.jsp"></jsp:include> --%>
   <jsp:include page="${main_jsp }"></jsp:include> 
  <jsp:include page="footer.jsp"></jsp:include>
<a id="backtotop" href="#top"><i class="fa fa-chevron-up"></i></a> 
<!-- JAVASCRIPTS --> 
<script src="../layout/scripts/jquery.min.js"></script> 
<script src="../layout/scripts/jquery.backtotop.js"></script> 
<script src="../layout/scripts/jquery.mobilemenu.js"></script> 
<script src="../layout/scripts/jquery.flexslider-min.js"></script>
</body>
</html>

 

 

로그인 처리

 

MemberVO.java (Class)

//Getter, Setter는 생략(실제로는 있어야함)
package doodoo.vo;
public class MemberVO {
	private String id, pwd, name, sex, birthday, email;
    private String post, addr1, addr2, tel, content, admin, login;
	private String tel1, tel2; //받을 때는 tel1, tel2 따로 받고 묶어서 한번에 처리할것임
	private String msg;
}

 

이런 MemberVO에 회원의 정보를 저장해왔었죠... 저걸 참고하면서!

아래와 같은 흐름으로 로그인 처리를 진행한다.

 

 

로그인이 완료되면, session에 유저 ID, 이름, 관리자 여부를 저장한다!

 

 

member-mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="doodoo.mapper.member-mapper">
	<!-- 로그인 처리(ID 존재여부 확인) -->
	<select id="memberIdCount" resultType="int" parameterType="String">
		SELECT COUNT(*)
		FROM project_member
		WHERE id=#{id}
	</select>
	<!-- 로그인 처리(비밀번호 확인) -->
	<select id="memberInfoData" resultType="MemberVO" parameterType="String">
		SELECT pwd, id, name, admin
		FROM project_member
		WHERE id=#{id}
	</select>
</mapper>

 

 

MemberDAO.java (Class)

package doodoo.dao;
import doodoo.vo.*;

import java.io.*;
import java.util.*;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MemberDAO {
  private static SqlSessionFactory ssf;
  static {
    try {
      Reader reader = Resources.getResourceAsReader("Config.xml");
      ssf = new SqlSessionFactoryBuilder().build(reader);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  public static MemberVO isLogin(String id, String pwd) {
    MemberVO vo = new MemberVO();
    SqlSession session = null;
    try {
      session = ssf.openSession();
      int count = session.selectOne("memberIdCount", id);
      if (count == 0) {
        vo.setMsg("NOID");
      } else {
        vo = session.selectOne("memberInfoData", id);
        if (pwd.equals(vo.getPwd())) {
          vo.setMsg("OK");
        } else {
          vo.setMsg("NOPWD");
        }
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    } finally {
      if (session != null)
        session.close();
    }
    return vo;
  }
}

 

 

MemberModel.java (Class)

package doodoo.model;

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

import controller.Controller;
import controller.RequestMapping;

import doodoo.dao.*;
import doodoo.MemberVO;

@Controller
public class MemberModel {
  //화면 출력만 해줌
  @RequestMapping("member/login.do")
  public String member_login(HttpServletRequest request, HttpServletResponse response) {
    return "../member/login.jsp"; //main에 출력하는거 아님! shadowBox에 올릴것임. -> shadowBox 안에서 처리를 해야 한다.
  }
  @RequestMapping("member/login_ok.do")
  public String member_login_ok(HttpServletRequest request, HttpServletResponse response) {
    //사용자 요청값을 받아온다.
    String id = request.getParameter("id");
    String pwd = request.getParameter("pwd");
    //DAO연동 -> mapper로 SQL 만들어놓고 DAO에서 메서드 처리
    MemberVO vo = MemberDAO.isLogin(id, pwd);
    String result = vo.getMsg();
    if (result.equals("OK")) {
      HttpSession session = request.getSession(); //세션에 저장해야 로그인 유지가 가능함
      session.setAttribute("id", vo.getId());
      session.setAttribute("name", vo.getName());
      session.setAttribute("admin", vo.getAdmin());
    }
    request.setAttribute("result", result);
    return "../member/login_ok.jsp"; //ajax에서 읽어갈것임
  }
  @RequestMapping("member/logout.do")
  public String member_logout(HttpServletRequest request, HttpServletResponse response) {
    HttpSession session = request.getSession();
    session.invalidate(); //session에 저장된 모든 데이터를 지운다.
    return "redirect:../main/main.do";
  }

 

 

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Login</title>
  <link href="https://fonts.googleapis.com/css?family=Asap" rel="stylesheet">
  <link rel="stylesheet" href="./style.css">
  <script type="text/javascript" src="http://code.jquery.com/jquery.js"></script>
  <script type="text/javascript">
  $(function(){
    $('#logBtn').on("click",function(){
      let id=$('#id').val();
      if(id.trim()==""){
        $('#id').focus();
        return;
      }
      let pwd=$('#pwd').val();
      if(pwd.trim()==""){
        $('#pwd').focus();
        return;
      }
      //서버로 전송
      $.ajax({
        type:'post',
        url:'../member/login_ok.do',
        data:{"id":id,"pwd":pwd},
        success:function(result){
          let res=result.trim();
          if(res==='NOID'){
            //ID가 없습니다.
            alert("ID 업슴!");
            $('#id').val("");
            $('#pwd').val("");
            $('#id').focus();
          }else if(res==='NOPWD'){
            //비밀번호가 틀립니다.
            alert("비번틀림!");
            $('#pwd').val("");
            $('#pwd').focus();
          }else{
            //정상 수행
            parent.location.href="../main/main.do";
          }
        }
      })
    })
  })
  </script>
</head>
<body>
<!-- partial:index.partial.html -->
<form class="login">
  <input type="text" placeholder="ID" id="id">
  <input type="password" placeholder="Password" id="pwd">
  <input type=button value="로그인" id="logBtn" class="button">
</form>
</body>
</html>

 

 

login_ok.jsp

login_ok.jsp는 딱 result 값을 받고 넘겨주는 역할만 한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
${result}

 

 

 

로그인 여부 / 사용자 유형에 따라 헤더 메뉴 다르게 하기

 

로그인을 하고 나면 session에 사용자의 정보가 저장되도록 처리했다.

main에 나오는 header.jsp에서 사용자에 따라 어떤 메뉴를 보여줄 것인지 달리 해 주자.

아래와 같이 <c:if> 를 사용해서  session의 값을 받아와 조건을 처리하면 된다.

 

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" %>
<%--테스트용 세션등록
  session.setAttribute("id",null);
  session.setAttribute("admin",null);
--%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div class="wrapper row1">
  <header id="header" class="clear"> 
    <div id="logo" class="fl_left">
      <h1><a href="../main/main.do">Gravity</a></h1>
    </div>
    <div class="fl_right">
      <ul class="inline">
      <c:if test="${sessionScope.id==null }"><!-- session에 id가 등록되지 않았다(미로그인 상태) -->
        <li><img src="../main/images/login.png" style="width:50px; height:50px" class="images" id="logImg" title="로그인"></li>
      </c:if>
      <c:if test="${sessionScope.id!=null }">
        <li><img src="../main/images/logout.png" style="width:50px; height:50px" class="images" id="logoutImg" title="로그아웃"></li>
      </c:if>
        <li><img src="../main/images/store2.png" style="width:100px; height:50px" class="images" id=""></li>
      </ul>
    </div>
  </header>
</div>
<div class="wrapper row2">
  <nav id="mainav" class="clear"> 
    <ul class="clear">
      <li class="active"><a href="../main/main.do">Home</a></li>
      <li><a class="drop" href="#">회원</a>
        <c:if test="${sessionScope.id==null }">
          <ul>
            <li><a href="../member/join.do">회원가입</a></li>
            <li><a href="../pages/full-width.html">아이디찾기</a></li>
            <li><a href="../pages/sidebar-left.html">비밀번호 찾기</a></li>
          </ul>
        </c:if>
        <c:if test="${sessionScope.id!=null }">
          <ul>
            <li><a href="../member/join.do">회원수정</a></li>
            <li><a href="../pages/full-width.html">회원탈퇴</a></li>
          </ul>
        </c:if>
      </li>
      <li><a class="drop" href="#">맛집</a>
        <ul>
          <li><a href="../food/food_find.do">지역별 맛집 찾기</a></li>
          <c:if test="${sessionScope.id!=null }">
            <li><a href="../food/food_find.do">맛집 추천</a></li>
            <li><a href="../pages/sidebar-left.html">맛집 예약</a></li>
          </c:if>
        </ul>
      </li>
      <li><a class="drop" href="#">레시피</a>
        <ul>
          <li><a href="../recipe/recipe_list.do">레시피 목록</a></li>
          <li><a href="../recipe/chef_list.do">쉐프</a></li>
          <c:if test="${sessionScope.id!=null }">
            <li><a href="../recipe/chef_make.do">쉐프 작품</a></li>
            <li><a href="../pages/sidebar-left.html">레시피만들기</a></li>
          </c:if>
        </ul>
      </li>
      <li><a class="drop" href="#">서울여행</a>
        <ul>
          <li><a href="../seoul/location.do">명소</a></li>
          <li><a href="../seoul/nature.do">자연/관광</a></li>
          <li><a href="../seoul/shop.do">쇼핑</a></li>
          <li><a href="../seoul/hotel.do">호텔</a></li>
          <li><a href="../seoul/guest.do">게스트하우스</a></li>
          <c:if test="${sessionScope.id!=null }">
            <li><a href="../seoul/guest.do">코스 추천</a></li>
          </c:if>
        </ul>
      </li>
     <li><a href="#">레시피 스토어</a></li>
     <li><a class="drop" href="#">커뮤니티</a>
       <ul>
         <li><a href="../freeboard/list.do">자유게시판</a></li>
            <li><a href="../board_reply/list.do">묻고답하기</a></li>
            <li><a href="../pages/sidebar-left.html">공지사항</a></li>
       </ul>
       </li>
     <c:if test="${sessionScope.id!=null }">
       <c:if test="${sessionScope.admin=='n' }">
         <li><a href="../mypage/mypage.do">마이페이지</a></li>
       </c:if>
       <c:if test="${sessionScope.admin=='y' }">
         <li><a href="../adminpage/adminpage.do">ADMIN페이지</a></li>
       </c:if>
     </c:if>
    </ul>
  </nav>
  </div>
</body>
</html>

 

 

그럼 짜잔~ 이렇게 할 수 있다~

 

 

 

댓글()