저번장에서는 회원가입을 하는 기능을 구현하였는데요
이번장에서는 로그인하는 기능을 구현해보도록 하겠습니다.
로그인 기능은 게시물의 상세보기(조회)와 같다고 생각하시면 됩니다.
일단 DB 쿼리로 데이터를 알맞게 잘 가져오는지 확인부터 해야겠죠?
테스트로 확인해보겠습니다
select identification, name, password
from user
where identification = "test" and password = "aaaa";
다음과 같이 조회가 되는데요
password를 추가한 이유는 회원탈퇴할 때 사용되기 때문에 추가했습니다.
이제 해당 쿼리를 mapper로 작성하겠습니다.
1. UserMapper 수정
<?xml version="1.0" encoding="UTF-8"?>
<!-- DTD 선언 -->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org/DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="userMapper">
<insert id="register">
insert into user(identification, password, name)
values( #{identification}, #{password}, #{name})
</insert>
<select id="login" resultType="UserVO">
select identification, name, password
from user
where identification = #{identification} and password = #{password}
</select>
</mapper>
resultType은 해당쿼리로 조회된 결과를 UserVO로 반환한다는 뜻입니다.
2. UserDAO 수정
package kr.co.web.persistence;
import kr.co.web.domain.UserVO;
public interface UserDAO {
public void register(UserVO vo) throws Exception;
public UserVO login(UserVO vo) throws Exception;
}
package kr.co.web.persistence;
import javax.inject.Inject;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import kr.co.web.domain.UserVO;
@Repository
public class UserDAOImpl implements UserDAO{
@Inject
private SqlSession session;
private static final String NS = "userMapper";
private static final String REGISTER = NS + ".register";
private static final String LOGIN = NS + ".login";
@Override
public void register(UserVO vo) throws Exception {
session.insert(REGISTER, vo);
}
@Override
public UserVO login(UserVO vo) throws Exception {
return session.selectOne(LOGIN, vo);
}
}
3. UserService 수정
package kr.co.web.service;
import kr.co.web.domain.UserVO;
public interface UserService {
public void register(UserVO vo) throws Exception;
public UserVO login(UserVO vo) throws Exception;
}
package kr.co.web.service;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.co.web.domain.UserVO;
import kr.co.web.persistence.UserDAO;
@Service
public class UserServiceImpl implements UserService {
@Inject
private UserDAO user;
@Override
public void register(UserVO vo) throws Exception {
user.register(vo);
}
@Override
public UserVO login(UserVO vo) throws Exception {
return user.login(vo);
}
}
4. UserController 수정
package kr.co.web.controller;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import kr.co.web.domain.UserVO;
import kr.co.web.service.UserService;
@Controller
@RequestMapping("/user/*")
public class UserController {
@Inject
private UserService service;
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
@RequestMapping(value = "/register", method = RequestMethod.GET)
public void registerGET() throws Exception {
logger.info("registerGET");
}
@RequestMapping(value = "/register", method = RequestMethod.POST)
public String registerPOST(UserVO vo, RedirectAttributes ra) throws Exception {
logger.info("registerPOST");
service.register(vo);
ra.addFlashAttribute("result", "registerOK");
return "redirect:/";
}
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String loginPOST(UserVO vo, HttpServletRequest req, RedirectAttributes ra) throws Exception {
logger.info("post login");
// HttpServletRequest를 사용하면 값을 받아 올수 있다.
HttpSession session = req.getSession();
UserVO login = service.login(vo);
if(login == null) {
session.setAttribute("user", null);
ra.addFlashAttribute("result", "loginFalse");
} else {
session.setAttribute("user", login);
String id = req.getParameter("identification"); // 확인용
ra.addFlashAttribute("result", "loginOK");
}
return "redirect:/";
}
}
사용자가 로그인창에서 아이디와 패스워드를 입력합니다.
아이디와 패스워드를 입력 후 로그인 버튼을 누르면
위의 loginPOST 메서드가 실행이 되는데요!
아까 위에서 진행했던 쿼리에서 아이디와 비밀번호로 ID 와 PW, NAME을 조회했죠?
사용자가 아이디와 비밀번호 입력폼에 본인의 아이디와 패스워드를 입력했을 때
UserVO login = service.login(vo);
테스트 id와 password로 설명드리겠습니다.
<!-- test info -->
identification : test
password : aaaa
위의 정보는 아이디가 test이고, 비밀번호가 aaaa인데
사용자가 오타로 비밀번호를 ssss라고 작성하면
UserVO login = service.login(vo); 부분에
test 와 ssss가 들어가겠죠?
하지만 아까 login 쿼리에서
DB에 있는 identification과 password와 일치한것을 조회하는데
DB에 있는 비밀번호는 aaaa니까 조회결과가 나오지 않습니다.
그렇기 때문에 login에는 nulll값이 들어가게 됩니다.
if문으로 login이 null이면 세션에 null값을 보내고
null이 아니면 로그인 정보가 맞는거겠죠?
로그인 정보가 일치하면
session.setAttribute로 login을 "user"에 담아 세션에 보냅니다. (model과 비슷)
5. home.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ page language="java" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<html>
<head>
<title>Home</title>
<script>
var result = '${result}'; // 쌍따음표 말고 따음표로 해야 데이터를 가져옴
if(result === "loginFalse") {
alert("로그인에 실패했습니다.");
} else if(result === "updateOK") {
alert("회원정보가 변경되었습니다.");
} else if(result === "loginOK") {
alert("로그인에 성공하였습니다.");
} else if(result === "removeOK") {
alert("회원 탈퇴를 성공하였습니다.");
} else if(result === "registerOK") {
alert("회원가입에 성공하였습니다.");
}
</script>
</head>
<a href="/board/listPage">게시판</a><br />
<body>
<c:if test="${user == null}">
<form method ="post" autocomplete="off" action="/user/login">
<div>
<label for="identification">아이디</label>
<input type="text" id="identification" name="identification" />
</div>
<div>
<label for="password">비밀번호</label>
<input type="password" id="password" name="password" />
</div>
<div>
<button type="submit">로그인</button>
</div>
</form>
</c:if>
<c:if test="${user == null}">
<button type="button" onclick="location.href='/user/register'">회원가입</button>
</c:if>
<c:if test="${user != null}">
<div>
<button type="button" onclick="location.href='/user/logout'">로그아웃</button>
<button type="button" onclick="location.href='/user/modify'">회원정보 수정</button>
<button type="button" onclick="location.href='/user/remove'">회원탈퇴</button>
</div>
</c:if>
<c:if test="${user != null }">
<div>
${user.name} 님 환영합니다.
</div>
</c:if>
</body>
</html>
form을 보시면 action 속성으로 post되는 주소를 정해줬기 때문에
버튼의 속성을 submit으로 설정해주면 action에 맞는 주소로 이동하게 됩니다.
아까 컨트롤러에서 로그인 정보를 "user"로 보냈죠?
저희는 로그인을 하고 해당 사용자의 이름을 출력하고 싶은데
로그인을 하지 않으면 이름이 출력되지 않겠죠?
그렇기 때문에 c:if 문과 아까 세션값인 "user"을 이용하여 확인 해볼겁니다.
user가 null이 아니면
test님 환영합니다.
를 보여주고 user가 null이라면 보여지지 않게 하는 코드입니다.
그리고 로그인에 실패했으면 경고창으로 로그인에 실패했다고 알려주고
성공했다면 성공했다는 알림을 발생하게 하는 기능은
아래 코드를 보시면 이해가 가실겁니다!!
<!-- loginPOST 메서드 -->
if(login == null) {
session.setAttribute("user", null);
ra.addFlashAttribute("result", "loginFalse");
} else {
session.setAttribute("user", login);
String id = req.getParameter("identification"); // 확인용
ra.addFlashAttribute("result", "loginOK");
}
<!-- home.jsp -->
var result = '${result}'; // 쌍따음표 말고 따음표로 해야 데이터를 가져옴
if(result === "loginFalse") {
alert("로그인에 실패했습니다.");
} else if(result === "loginOK") {
alert("로그인에 성공하였습니다.");
}
해당 부분은 어렵지 않기 때문에 이후에 나오는 것들은 생략하겠습니다!!!!
궁금하신 분들은
https://github.com/jinyeanseok/blog
jinyeanseok/blog
blog project. Contribute to jinyeanseok/blog development by creating an account on GitHub.
github.com
저의 깃허브 사이트에 가셔서 궁금한점을 찾아보시면 좋을 것 같습니다.
로그아웃 기능
로그아웃 기능은 간단합니다.
로그인을 했을 때 로그아웃 버튼이 있어야 하기에
home.jsp에 다음과 같은 코드를 추가합니다.
<button type="button" onclick="location.href='/user/logout'">로그아웃</button>
이제 UserController에 로그아웃 메서드를 만들겠습니다.
<!-- UserController -->
@RequestMapping(value ="/logout", method = RequestMethod.GET)
public String logout(HttpSession session) throws Exception {
logger.info("logout");
session.invalidate();
return "redirect:/";
}
위 코드는 파라미터에 HttpSession을 이용하여 세션값을 가져옵니다.
위에서 로그아웃 버튼을 만들었죠?
로그아웃 버튼을 클릭하면 logout 메서드가 실행되어
session.invalidate(); 로
로그아웃이 되게 하는데요?
사실 invalidate는 세션을 삭제하는것이 아닌 세션을 무효화시키는 것입니다.
'JAVA > blog' 카테고리의 다른 글
회원(4) - 회원탈퇴 (0) | 2020.07.31 |
---|---|
회원(3) - 비밀번호 변경 (0) | 2020.07.31 |
회원 (1) - 가입 기능 (0) | 2020.07.31 |
댓글 구현(3) - 게시판 댓글 수정, 삭제 (0) | 2020.07.29 |
댓글 구현(2) - 게시판 댓글 작성 (0) | 2020.07.27 |