📕일단 VO(Value Ojbect)를 먼저 만든다
package kr.or.ddit.vo;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* JavaBean 규약
* ValueObject, DataTransferObject, Model, Bean
* ex) MemberVO, MemberDTO, MemberModel, MemberBean
*
* 1. 값을 저장할 속성(property) 정의
* 2. 캡슐화
* 3. 캡슐화된 데이터에 접근할 인터페이스 제공(getter/setter)
* get[set]프로퍼티명에서 첫문자만 대문자, camel case 적용
* 4. 상태 비교 메소드 제공 hashcode equals()
* 5. 상태 확인 메소드 제공 == toString
* 6. 직렬화
*
* 회원관리와 인증시스템을 위한 Domain Layer
*/
public class MemberVO implements Serializable{
private String memId;
//password의 노출을 막기위해 transient와 JsonIgnore를 이용한다
@JsonIgnore
private transient String memPass;
private String memName;
public String getMemId() {
return memId;
}
//getter와 setter만들기
public void setMemId(String memId) {
this.memId = memId;
}
public String getMemPass() {
return memPass;
}
public void setMemPass(String memPass) {
this.memPass = memPass;
}
public String getMemName() {
return memName;
}
public void setMemName(String memName) {
this.memName = memName;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((memId == null) ? 0 : memId.hashCode());
return result;
}
//hashCode and equals를 통해 memId의 중복체크
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MemberVO other = (MemberVO) obj;
if (memId == null) {
if (other.memId != null)
return false;
} else if (!memId.equals(other.memId))
return false;
return true;
}
//toString에서도 password노출을 막기위해 password는 체크하지않는다
@Override
public String toString() {
return "MemberVO [memId=" + memId + ", memName=" + memName + "]";
}
}
📕그다음 DAO와 Service를 만들어야하지만 일단은 구현하지 않아도 사용할 수 있도록 Interface부터 구현한다.
✔ServiceInterface
package kr.or.ddit.member.service;
import kr.or.ddit.member.exception.AuthenticateException;
import kr.or.ddit.vo.MemberVO;
public interface AuthenticateService {
/**
* 아이디와 비밀번호 기반의 인증 처리
* @param input
* @return 인증에 성공한 경우, 해당 사용자의 정보를 가진 VO
* @throws AuthenticateException 인증 실패
*/
public MemberVO authenticate(MemberVO input) throws AuthenticateException;
}
✔DAOInterface
package kr.or.ddit.member.dao;
import kr.or.ddit.vo.MemberVO;
/**
* 회원관리와 인증시스템을 위한 Persistence Layer
*/
public interface MemberDAO {
/**
* PK로 회원 한명의 정보 조회
* @param memId
* @return 존재하지 않는 경우, null반환.
*/
public MemberVO selectMemberForAuth(String memId);
}
📕Interface를 Implement한다
✔DAOImpl
package kr.or.ddit.member.dao;
import java.util.LinkedHashMap;
import java.util.Map;
import kr.or.ddit.vo.MemberVO;
public class MemberDAOImpl_InMemory implements MemberDAO {
private Map<String, MemberVO> memberDB;
public MemberDAOImpl_InMemory() {
super();
memberDB = new LinkedHashMap<>();
MemberVO a001VO = new MemberVO();
a001VO.setMemId("a001");
a001VO.setMemPass("java");
a001VO.setMemName("김은대");
memberDB.put("a001", a001VO);
MemberVO b001VO = new MemberVO();
b001VO.setMemId("b001");
b001VO.setMemPass("java");
b001VO.setMemName("이쁜이");
memberDB.put("b001", b001VO);
}
@Override
public MemberVO selectMemberForAuth(String memId) {
return memberDB.get(memId);
}
}
✔serviceImpl
package kr.or.ddit.member.service;
import kr.or.ddit.member.dao.MemberDAO;
import kr.or.ddit.member.dao.MemberDAOImpl_InMemory;
import kr.or.ddit.member.exception.AuthenticateException;
import kr.or.ddit.vo.MemberVO;
public class AuthenticateServiceImpl implements AuthenticateService {
// 의존 객체를 직접 인스턴스화. 결합력 최상.
private MemberDAO dao = new MemberDAOImpl_InMemory();
@Override
public MemberVO authenticate(MemberVO input) throws AuthenticateException {
MemberVO saved = dao.selectMemberForAuth(input.getMemId());
if(saved!=null) {
String inputPass = input.getMemPass();
String savedPass = saved.getMemPass();
if(savedPass.equals(inputPass)) {
return saved;
}
}
throw new AuthenticateException(input.getMemId());
}
}
📕Controller_login
package kr.or.ddit.member.controller;
import java.io.IOException;
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 javax.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import kr.or.ddit.member.exception.AuthenticateException;
import kr.or.ddit.member.service.AuthenticateService;
import kr.or.ddit.member.service.AuthenticateServiceImpl;
import kr.or.ddit.vo.MemberVO;
/**
* 1. 둘중의 하나 혹은 모든 파라미터가 누락되면, 400 에러 전송
* 2. 인증 실패라면, loginForm으로 이동("로그인에 실패했음" 공유, attribute name : message)
* -> loginForm에서 "로그인에 실패했음" 이라는 메시지를 swal로 출력.
* 3. 인증 성공시, 웰컴 페이지로 이동. (인증에 성공한 사용자의 VO를 공유, attribute name : authMember)
* -> "김은대님 로그인" 메시지 출력.
*/
@WebServlet("/login/loginProccess")
public class LoginProcessControllerServlet extends HttpServlet {
private AuthenticateService service = new AuthenticateServiceImpl();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//세션을 통한 공격을 막기위한 방지코드
HttpSession session = req.getSession();
if(session.isNew()) {
resp.sendError(400);
return;
}
//폼에서 Parameter값을 받아온다
req.setCharacterEncoding("utf-8");
String memId = req.getParameter("memId");
String memPass = req.getParameter("memPass");
//VO생성 뒤 파라미터 값들을 넣어준다
MemberVO input = new MemberVO();
input.setMemId(memId);
input.setMemPass(memPass);
boolean valid = validate(input);
String viewName = null;
if(valid) {
try {
MemberVO saved = service.authenticate(input);
session.setAttribute("authMember", saved);
viewName= "/";
}catch(AuthenticateException e) {
String message = "로그인 실패";
session.setAttribute("message", message);
viewName = "/login/loginForm.jsp";
}
}else {
session.setAttribute("message", "필수 파라미터 누락");
}
resp.sendRedirect(req.getContextPath() + viewName);
}
//StringUtils를 통한 null방지
private boolean validate(MemberVO input) {
boolean valid = true;
if(StringUtils.isBlank(input.getMemId())) {
valid = false;
}
if(StringUtils.isBlank(input.getMemPass())) {
valid = false;
}
return valid;
}
}
📕Controller_logout
package kr.or.ddit.member.controller;
import java.io.IOException;
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 javax.servlet.http.HttpSession;
@WebServlet("/login/logout")
public class LogoutCotrollerServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
if(session.isNew()) {
resp.sendError(400, "유효 세션이 아님.");
return;
}
// session.removeAttribute("authMember");
session.invalidate();//더이상 세션을 사용할 수 없는 상태로 만들어줌
resp.sendRedirect(req.getContextPath()+"/");
}
}
📕view_form
<%@page import="org.apache.commons.lang3.StringUtils"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<jsp:include page="/includee/preScript.jsp"/>
<%
String message = (String) session.getAttribute("message");
session.removeAttribute("message"); // flash attribute
if(StringUtils.isNotBlank(message)){
%>
<script>
alert("<%=message%>");
// Swal.fire({
// icon: 'error',
// title: 'Oops...',
<%-- text: '<%=message%>', --%>
// })
</script>
<%
}
%>
</head>
<body>
<form action="<%=request.getContextPath() %>/login/loginProccess" method="post">
<ul>
<li>아이디 : <input type="text" name="memId" /></li>
<li>비밀번호 : <input type="password" name="memPass" /></li>
<li>
<input type="submit" value="로그인"/>
</li>
</ul>
</form>
<jsp:include page="/includee/postScript.jsp"/>
</body>
</html>
'웹기반 애플리케이션' 카테고리의 다른 글
JSP📃_Scope(영역) (0) | 2023.03.17 |
---|---|
JSP📃_copy (0) | 2023.03.16 |
JSP📃_Application (0) | 2023.03.16 |
JSP📃_JSP 스펙에서 제공되는 기본객체 (0) | 2023.03.16 |
JSP📃_Buffer (0) | 2023.03.16 |