안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
로그인
viewName이 null인 경우, 요청 url을 기준으로 jsp위치를 추론
/member/memberLogin.do → member/memberLogin으로 추론
@GetMapping("/memberLogin.do")
public void memberLogin() {
}
memberLogin.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="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<!-- bootstrap js: jquery load 이후에 작성할것.-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<!-- bootstrap css -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
<!-- 사용자작성 css -->
<link rel="stylesheet" href="${pageContext.request.contextPath }/resources/css/style.css" />
<c:if test="${not empty msg}">
<script>
alert("${msg}");
</script>
</c:if>
</head>
<body>
<!-- Modal시작 -->
<!-- https://getbootstrap.com/docs/4.1/components/modal/#live-demo -->
<div class="modal fade" id="loginModal" tabindex="-1" role="dialog"
aria-labelledby="loginModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="loginModalLabel">로그인</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<!--로그인폼 -->
<!-- https://getbootstrap.com/docs/4.1/components/forms/#overview -->
<form
action="${pageContext.request.contextPath}/member/memberLogin.do"
method="post">
<div class="modal-body">
<input
type="text" class="form-control" name="memberId"
placeholder="아이디" required>
<br />
<input
type="password" class="form-control" name="password"
placeholder="비밀번호" required>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-outline-success">로그인</button>
<button type="button" class="btn btn-outline-success" data-dismiss="modal">취소</button>
</div>
</form>
</div>
</div>
</div>
<!-- Modal 끝-->
<script>
$(loginModal).modal().on("hide.bs.modal", (e) => {
location.href = "${pageContext.request.contextPath}/";
});
</script>
</body>
</html>
Controller
MemberController
matches() - 일치 여부 검사
@SessionAttributes - session scope에 속성 저장
@Controller
@RequestMapping("/member")
@Slf4j
@SessionAttributes({"loginMember"})
public class MemberController {
@Autowired
private MemberService memberService;
@Autowired
private BCryptPasswordEncoder bcryptPasswordEncoder;
@PostMapping("/memberLogin.do")
public String memberLogin(@RequestParam String memberId, @RequestParam String password, Model model, RedirectAttributes redirectAttr) {
// 1. memberId로 조회
Member member = memberService.selectOneMember(memberId);
String location = "/";
// 2. member가 null이 아니면서, 비밀번호가 일치하면 로그인 성공
if(member != null && bcryptPasswordEncoder.matches(password, member.getPassword())) {
// model을 통해 session scope에 속성 저장 : 클래스레벨에 @SessionAttributes로 등록
model.addAttribute("loginMember", member);
}
// 로그인실패
else {
redirectAttr.addFlashAttribute("msg", "아이디 또는 비밀번호가 일치하지 않습니다.");
location += "member/memberLogin.do";
}
return "redirect:" + location;
}
}
BcryptPasswordEncoder의 matches() 메소드를 이용하여 입력한 비밀번호와 일치하는 지 검사를 했습니다.
만일 일치하다면 model을 통해 session scope에 속성으로 저장되도록 하였습니다.
Model은 기본적으로 request scope에 저장되지만 @SessionAttributes로 등록을 함으로써 session scope에 저장할 수도 있습니다.
Service
MemberService interface 생략
MemberServiceImpl
@Override
public Member selectOneMember(String memberId) {
return memberDao.selectOneMember(memberId);
}
Dao
MemberDao interface
Member selectOneMember(String memberId);
member-mapper.xml
<mapper namespace="com.ce.spring2.member.model.dao.MemberDao">
<select id="selectOneMember" resultType="member">
select * from member where member_id = #{memberId}
</select>
</mapper>
로그인 실패 시
로그인 성공 시
로그아웃
Controller
MemberController
SessionStatus#setComplete - 세션을 다 사용했다는 의미, 만료처리 (세션객체는 유지하되, 안에 내용만 제거)
/**
* @SessionAttributes로 세션 관리를 한다면, SessionStatus#setComplete으로 만료처리!
*/
@GetMapping("/memberLogout.do")
public String memberLogout(SessionStatus sessionStatus) {
if(!sessionStatus.isComplete()) {
// 세션을 다 사용했다는 의미 - 만료 처리(세션 객체는 유지하되, 안에 내용만 제거)
sessionStatus.setComplete();
}
return "redirect:/";
}
@SessionAttributes로 세션관리를 하기 때문여 SessionStatus#setComplete로 만료처리를 해주었습니다.
세션 객체는 그대로 유지하되, 안에 내용(속성)만 제거하는 것이므로 로그아웃 처리가 되어도 세션 아이디는 동일할 것입니다.
로그인 - 세션 아이디 : 2DA5597...
로그아웃 - 세션 아이디 : 2DA5597...
로그아웃 처리가 되어도 세션아이디가 그대로 유지 되고 있는 것을 확인할 수 있습니다.
- 세션 객체를 효율적으로 관리!
'Java > Spring' 카테고리의 다른 글
Spring) 회원 정보 수정 (0) | 2022.08.23 |
---|---|
Spring) Model (ModelAndView, ModelMap, Model), @ModelAttribute, @SessionAttribute, @SessionAttributes (1) | 2022.08.23 |
Spring) 암호화 처리 - BCryptPasswordEncoder (0) | 2022.08.22 |
Spring) 회원 가입 처리하기 (index페이지에서 alert 작동 안되는 원인 파악) (0) | 2022.08.19 |
Spring) Dev 목록 가져오기 (0) | 2022.08.18 |