본문 바로가기
프로그래밍/스프링 & 스프링 부트

스프링 ajax 로그인 로그아웃 구현

by 밍구몬 2019. 5. 20.

이번 예제는 로그인과 로그아웃 처리를 어떻게 하는지만 간단하게 설명하기 위해 만들었다.

데이터 베이스는 OracleDB를 사용하였다.

 

DB 세팅

create table member(
user_id varchar2(10) primary key,
passwd varchar2(20) not null
);

insert into member(user_id,passwd) values('test','test');

간단하게 구현하기 위하여 ID와 password만 만들었고, test계정을 직접 입력해 주었다.

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Insert title here</title>
	<script src="resources/jQuery/jquery-3.4.1.min.js"></script>
</head>

<body>
	<button id="board">게시판</button>
	<button id="login" id="login" >로그인</button>
</body>

<script type="text/javascript">
	$(document).ready(function(e){
		$('#board').click(function() {
			location.href="getBoardList.do";
		});
		$('#login').click(function() {
			location.href="login.do";
		});
	});
</script>

</html>

기본 페이지에 게시판과 로그인 페이지로 가기위한 버튼을 만들었다.

 

LoginController.java

package com.wipia.study.controller;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.wipia.study.domain.MemberVO;
import com.wipia.study.service.MemberService;

@Controller
@SessionAttributes("login")
public class LoginController {

	@Autowired
	private MemberService memberService;
	
	@RequestMapping("/login.do")
	public String login() {
		return "login";
	}
	
	//로그인 처리
	@RequestMapping(value="/loginCheck.do")
	public ModelAndView loginCheck(@ModelAttribute MemberVO vo,HttpSession session) {
		
		boolean result = memberService.loginCheck(vo, session);
		ModelAndView mav = new ModelAndView();
		
		mav.setViewName("login");
		
		if(result) {
			mav.addObject("msg","성공");
		}else {
			mav.addObject("msg","실패");
		}
		
		return mav;
	}
	
	//로그아웃 처리
	@RequestMapping("logout.do")
	public ModelAndView logout(HttpSession session) {
		
		memberService.logout(session);
		ModelAndView mav = new ModelAndView();
		mav.setViewName("login");
		mav.addObject("msg", "logout");
		
		return mav;
	}
	
}

login.do는 그냥 로그인 페이지로, loginCheck는 아이디와 패스워드가 맞는지 체크하여 msg에 결과를 저장하고 login페이지로 다시 이동시킨다.

 

MemberVO.java

package com.wipia.study.domain;

public class MemberVO {

	private String userId;
	private String passwd;
	
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getPasswd() {
		return passwd;
	}
	public void setPasswd(String passwd) {
		this.passwd = passwd;
	}
	
	@Override
	public String toString() {
		return "LoginVO [userId=" + userId + ", passwd=" + passwd + "]";
	}
	
}

MemberService.java

package com.wipia.study.service;

import javax.servlet.http.HttpSession;

import com.wipia.study.domain.MemberVO;

public interface MemberService {

	//로그인 체크
	public boolean loginCheck(MemberVO vo,HttpSession session);
	
	//로그 아웃
	public void logout(HttpSession session);
	
}

MemberServiceImpl.java

package com.wipia.study.service.impl;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.wipia.study.dao.MemberDAO;
import com.wipia.study.domain.MemberVO;
import com.wipia.study.service.MemberService;;

@Service
public class MemberServiceImpl implements MemberService {

	@Autowired
	MemberDAO dao;
	
	@Override
	public boolean loginCheck(MemberVO vo,HttpSession session) {
		
		boolean result = dao.loginCheck(vo);
		if (result == true) {	//true 일경우 세션 등록
			//세션 변수 등록
			session.setAttribute("userId",vo.getUserId());
		}
		
		return result;
	}

	@Override
	public void logout(HttpSession session) {
		dao.logout(session);
	}
	
	
}

MemberService를 상속받아 구체적인 내용을 작성한다.

login버튼을 눌렀을 경우 dao에서 loginCheck를 하여 true인지 false인지를 반환해준다. true일 경우 세션 변수에 userId를 넣는다.

로그아웃 버튼을 눌렀을 경우에는 dao에 세션 정보를 넘겨서 처리한다.

 

MemberDAO.java

package com.wipia.study.dao;

import javax.servlet.http.HttpSession;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.wipia.study.domain.MemberVO;

@Repository
public class MemberDAO {

	@Autowired
	SqlSession sqlSession;
	
	//로그인 체크
	public boolean loginCheck(MemberVO vo) {
		System.out.println("===> Mybatis로 loginCheck() 기능 처리");
		String name = sqlSession.selectOne("memberMapper.loginCheck",vo);
		
		// 검색이 안되면 0을 반환해주기 때문에 0과 비교해서 참이면 false, 틀리면 true를 반환
		return (Integer.parseInt(name)==0)?false:true;
	}
	
	//로그 아웃
	public void logout(HttpSession session) {
		System.out.println("===> 로그아웃 기능 처리");
		session.invalidate();
	}
	
}

로그인 버튼을 눌렀을 경우 selectOne을 이용하여 mybatis에 vo정보를 넘겨준고,

로그아웃 버튼을 눌렀을 때는 session.invalidate()로 세션을 소멸 시킨다.

 

memberMapper.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="memberMapper">

	<select id="loginCheck" resultType="String">
		<![CDATA[
			SELECT count(*) FROM member
			WHERE user_id = #{userId} AND passwd = #{passwd}
		]]>
	</select>

</mapper>

검색하는 쿼리문을 입력해 준다.

 

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	
	<!-- 자동으로 카멜케이스 규칙으로 변환 -->
	<settings>
		<setting name="mapUnderscoreToCamelCase" value="true"/>
	</settings>
	
	<typeAliases>
		<package name="com.wipia.study.domain"/>
	</typeAliases>
	
	
	<!-- 오라클에서 Long타입 가져오기 위한 핸들러 -->
	<typeHandlers>
        <typeHandler handler="com.wipia.study.handler.CLOBHandler" javaType="String" jdbcType="LONGVARCHAR"/>
    </typeHandlers>

	
</configuration>

이전 예제에서 만들어 주었지만, 안본사람이 있을까봐 적어 놓는다.

 

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<%@taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>로그인</title>
	<script src="resources/jQuery/jquery-3.4.1.min.js"></script>
</head>
<body>
	<h1>로그인 페이지</h1>
	<hr />
		<c:choose>
			<c:when test="${empty sessionScope.userId}">
			<!-- 로그인이 안되어 있으면 -->
				<form id="loginFrm" name="loginFrm" action="loginCheck.do">
					<table>
						<tr>
							<td>아이디</td>
							<td><input type="text" name="userId" id="userId" placeholder="10글자" maxlength="10"></td>
						</tr>
						<tr>
							<td>패스워드</td>
							<td><input type="password" name="passwd" id="passwd" maxlength="20"></td>
						</tr>
						<c:if test="${msg == '실패'}">
							<tr>
								<td colspan=2>
									아이디 또는 패스워드가 틀렸습니다.
								</td>
							</tr>
						</c:if>
						<tr>
							<td colspan=2>
								<input type="button" id="login" value="로그인" />
							</td>
						</tr>
					</table>
				</form>
			</c:when>
			<c:otherwise>
				<h3>${sessionScope.userId}님 환영합니다.</h3>
				<a href="logout.do">로그아웃</a>
			</c:otherwise>
		</c:choose>
</body>
<script type="text/javascript">
	$(document).ready(function(e){
		$('#login').click(function(){

			// 입력 값 체크
			if($.trim($('#userId').val()) == ''){
				alert("아이디를 입력해 주세요.");
				$('#userId').focus();
				return;
			}else if($.trim($('#passwd').val()) == ''){
				alert("패스워드를 입력해 주세요.");
				$('#passwd').focus();
				return;
			}
			
			//전송
			$('#loginFrm').submit();
		});
		
	});
</script>
</html>

로그인 버튼을 클릭했을 경우 아이디와 패스워드 널 값을 체크하여 널이 아니라면 loginCheck.do로 전송한다.

세션아이디를 검색해 비어있으면, 로그인 화면이 나오고, 세션아이디값이 있으면 아이디+님 환영합니다가 나오도록 하였다.