[ 로그인 시 ]
1. 클라이언트가 ID PW 입력 ->
2. 전달 받은 ID PW를 DB에서 일치 확인 -> service, dao 에서 반환
3. if 결과 == o x
4-1. 일치하는게 존재하면 :
Session 객체에 담아서 브라우저 종료시까지 정보가 저장되도록 한다. (활동 없으면 1800초 후 사라지도록 설정)
session.setAttribute("loginMember" , loginMember);
session.setMaxInactiveInterval(1800);
+아이디 저장 체크 시 쿠키를 활용해서 쿠키를 내보내준다.
Cookie cookie = new Cookie("saveId", memberId);
-> saveId라는 Key 와 해당 id를 value로 가지는 Cookie 객체 생성
-> 체크시 쿠키 유효기간을 설정해주고 체크가 없으면 0으로 설정해 쿠키가 사라지게한다.
->쿠키 파일이 사용되어질 경로를 지정한다. (getContextPath == 메인부터 모두에서)
->response 객체에 해당 cookie를 추가해준다.
Cookie cookie = new Cookie("saveId",memberId);
if(req.getParameter("save")!=null) {
cookie.setMaxAge(60*60*24*30);
}else {
cookie.setMaxAge(0);
}
cookie.setPath(req.getContextPath());
resp.addCookie(cookie);
resp.sendRedirect(req.getContextPath());
*Servlet에서 응답 화면을 지정하는 방법 두가지.
1) forward : 요청 위임식으로
-- req, resp를 전달해서 화면을 만들게 해준다. (req, resp 유지)
2) redirect : 재요청식
--req와 resp를 삭제하고 다시 생성 / 다른 주소를 재요청한다.
4-2. 일치하지 않는다면 alert() 를 띄우고 돌아간다.
==> 로그인이 완료 된 경우
jsp 파일에서 <c:when> 과 <c:otherwise> 에서
sessionScope.loginMember 가 비어있는지 조건에 따라 test 구문을 넣어 표시 정보를 다르게 할 수 있다.
<c:choose>
<c:when test="${empty sessionScope.loginMember}">
<li></li>
</c:when>
<c:otherwise>
<li></li>
</c:otherwise>
</c:choose>
[로그아웃 시]
--> 반대로 session에서 회원 정보를 제거해주면 된다.
//session 객체 얻어오기
HttpSession session = req.getSession();
session.invalidate();
==> session을 통째로 무효화
(session의 로그인 아이디만 삭제도 가능하지만 다른 임시 정보들이 저장된 경우도 있으므로 바람직하지 않다.)
resp.sendRedirect(req.getContextPath());
-->리다이렉트
[비밀번호 암호화]
회원가입 같은 경우 비밀번호는 암호화되어 저장될 필요가 있다.
이를 위해 getParameter단계에서 사전에 아예 암호화되도록
Filter를 이용해 암호화된 정보가 getParameter 되도록 오버라이딩을 해준다.
1)필터 생성
%%%%%
필터? 클아이언트 요청 시 생성되는 HttpServletRequest, HttpServletResponse
이 두 객체가 요청 응답을 처리하는 Servlet/JSP에 도달하기 전/후 처리를 하는 클래스이다.
필터는 여러 개를 연쇄적으로 연결할 수 있다.(FilterChain)
필터의 생명 주기 : init -> doFilter -> destroy 반복
--> 모두 끝나면 필터의 매핑과 해당 서블릿의 매핑까지 확인한다.
@WebFilter(filterName = "encrypFiter" , urlPatterns = {"적용주소"})
public class EncrypFilter implements Filter{
public void init(FilterConfig fConfig) throws ServletException {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//HttpServletRequest, HttpServletResponse의 부모타입으로 매개변수가 선언됨
//다형성으로 모두 잡아서 필터링 == 부모 부분만 사용 가능 => 다운캐스팅 해서 사용
HttpServletRequest req= (HttpServletRequest)request;
// HttpServletResponse resp = (HttpServletResponse)response;
//필터링 확인
if(req.getMethod().equals("POST")) {
//POST방식 요청일 경우( 비밀번호 입력이 포함되면 무조건 POST방식 )
EncryptWrapper encWrapper = new EncryptWrapper(req);
// req 요청 객체를 EncrytWrapper로 감싸기
// 오버라이딩 사용 가능
//기존 req 대신 encWrapper를 Servlet으로 전달
chain.doFilter(encWrapper, response);
}
else {
chain.doFilter(request, response);
//다음 필터로 요청 응답 전달, 없으면 Servlet/JSP로 전달
}
}
2) getParameter 오버라이딩
==>HttpServletRequestWrapper : 클라이언트 요청을 감싸서 가공하는 객체
--> 이 객체를 상속받은 클래스를 생성해 오버라이딩을 진행한다.
HttpServletRequestWrapper는 매개변수 1개짜리 생성자만 존재한다.
이 클래스에서 오버라이딩 해서 getParameter 시 전달받은 name값이 pw인 경우들을 추가해
일반적인 경우 부모의 방식을 따르고
비밀번호에 해당하는 경우 SHA-512 해쉬함수를 이용한 암호화를 반환한다.
public class EncryptWrapper extends HttpServletRequestWrapper {
public EncryptWrapper(HttpServletRequest request) {
super(request);
}
//getParameter() 메소드를 오버라이딩
@Override
public String getParameter(String name) {
//매개변수로 memberPw가 넘어온 경우 암호화를 진행
//아닌경우 원래 getParameter() 동작을 수행
String value = null;
switch(name) {
case "memberPw": case "pwd1":
value = getSha512(super.getParameter(name));
break;
default :value = super.getParameter(name);
}
return value;
}
/** SHA-512 해쉬 함수를 이용하여 문자열 암호화를 진행하는 메소드
* @param pwd
* @return encPwd
*/
private String getSha512(String pwd) {
// 1. 암호화된 비밀번호를 저장할 변수 선언
String encPwd = null;
// 2. 해쉬 함수를 수행하는 객체를 저장할 변수 선언
// 해쉬 함수 : 특정 값을 여러 단계의 연산을 거쳐 일정 길이의 무작위 값을 얻어내는 함수
MessageDigest md = null;
try {
// 3. SHA-512 방식의 해쉬함수를 수행할 수 있는 객체를 얻어옴
md = MessageDigest.getInstance("SHA-512");
// 4. md를 이용해 문자열 암호를 하기 위해 byte 배열로 변환
byte[] bytes = pwd.getBytes(Charset.forName("UTF-8"));
// 5. md 객체에 바이트로 변환된 비밀번호를 전달하여 암호화를 수행
md.update(bytes);
// 6. md 객체에서 암호화된 내용을 꺼내옴
// Base64 : 바이트 코드를 문자열로 바꾸는 라이브러리
encPwd = Base64.getEncoder().encodeToString(md.digest());
// md.digest() : 암호화된 코드를 꺼내옴
System.out.println("암호화 전 : " + pwd);
System.out.println("암호화 후 : " + encPwd);
}catch (NoSuchAlgorithmException e) {
// SHA-512 해쉬함수가 없는 경우 발생
e.printStackTrace();
}
return encPwd;
}
}