[요청흐름]
클라이언트 -> 요청 -> HttpServletRequest -> 필터 -> 요청처리 Servlet
HttpServletResponse
생성
📌 비밀번호 암호화
- 로그인
- 회원가입
- 비밀번호 변경
- 회원 탈퇴
0. index.jsp
① 고객이 inputEmail / inputPw 입력 했다! servlet으로 가야하는데 ! filter을 만들어!
암호화 처리를 해준다.
<form action="member/login" method="post" name="login-form">
<!-- 아이디(이메일)/비밀번호/로그인버튼 영역 -->
<fieldset id="id-pw-area">
<section>
<input type="text" name="inputEmail" placeholder="아이디(이메일)"
value="${cookie.saveId.value}">
<%--현재 페이지 쿠키 중 "savdId" 의 내용을 출력--%>
<input type="password" name="inputPw" placeholder="비밀번호">
</section>
<section>
<button>로그인</button>
</section>
</fieldset>
1. 필터 만들기
클라이언트 > 요청 > HttpServletRequest
1. 암호를 가져올 수는 있지만 암호화 해서 다시 세팅하는 방법은 불가능
- 비밀번호는 HttpServletRequest에 담겨 있음 > 암호화를 진행하려고 하는데 필터에서는 불가능
2. wrapper 클래스를 이용해서 다시 세팅을 할 수 있다.
- HttpServletRequest의 메소드를 오버라이딩(재정의)통해서 비밀번호 암호화 진행
//암호화를 적용해야되는 요청 : 로그인, 회원가입, 비밀번호변경, 회원탈퇴
//필터가 적용될 url이 여러개인 경우 : String 배열 초기화 형태 {}로 작성
@WebFilter(filterName="encryptFilter",
urlPatterns = {"/member/login",
"/member/signUp",
"/member/myPage/ChangePw",
"/member/myPage/secession",
})
public class EncryptFilter extends HttpFilter 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에 담겨 있음
//doFilter 메소드 매개변수는 부모타입인 ServletRequest
// -> 다운캐스팅 필요
HttpServletRequest req = (HttpServletRequest)request;
// 파라미터를 다시 세팅하는 방법은 필터에서 불가능함
// -> servlet의 Wrapper 클래스를 이용해서
// HttpServletRequest의 메소드를 오버라이딩 할 수 있다.
// -> 오버라이딩(재정의)를 통해서 비밀번호 암호화 진행
chain.doFilter(request, response);
}
2. 클래스 만들기 (wrapper)
① extends HttpServletRequestWrapper 상속 받기
- HttpServletRequestWrapper : 클라이언트 요청 객체 HttpSerlvetRequest를 오버라이딩 하는 방법을 제공하는 클래스
② EncryptWrapper 매개변수 생성자 만들기
- Wrapper 클래스 생성 시 반드시 HttpServletRequest 객체를 매개변수로 전달해야한다.
③ getParameter() 오버라이딩 해주기
④ 암호화 메소드 만들기
- 해시 함수 : 어떤 문자열이든 일정한 길이의 무작위 문자열로 변환하는 함수 (중복)
package edu.kh.community.common.wrapper;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class EncryptWrapper extends HttpServletRequestWrapper{
//HttpServletRequestWrapper
// - 클라이언트 요청 객체 HttpSerlvetRequest를 오버라이딩 하는 방법을 제공하는 클래스
// 생성자가 작성되어 있으면 컴파일러가 기본 생성자를 자동으로 추가 안함
// -> Wrapper 클래스 생성 시 반드시 HttpServletRequest 객체를 매개변수로 전달해야한다.
public EncryptWrapper(HttpServletRequest request) {
super(request);
}
//getParameter() 오버라이딩
@Override
public String getParameter(String name) {
//매개변수 name :input 태그의 name 속성 값
//super.getParameter(name): 기존 getParameter()메소드 / 부모가 가지고 있는 input태그의 name 속성값
String value = null;
switch(name) {
case "inputPw" :
case "memebrPW" :
//입력된 비밀번호를 얻어와서 getsha512( ) 수행하고 value 값에 반환 받기
value = getSha512(super.getParameter(name));
break;
//암호화 되는 경우가 아니라면 기존 getParameter()메소드의 형태를 유지
default : value = super.getParameter(name);
}
return value;
}
//암호화 메소드 (SHA-512 해시 함수)
//해시 함수 : 어떤 문자열이든 일정한 길이의 무작위 문자열로 변환하는 함수 (중복X)
private String getSha512(String pw) {
//매개변수 pw : 암호화 되기 전 비밀번호
//암호화된 비밀번호 저장할 변수
String encryptPw = null;
// 1. 해시 함수를 수행할 객체를 참조할 변수 선언
MessageDigest md = null;
try {
//2. SHA-512 방식의 해시 함수를 수행할 수 있는 객체를 얻어옴
md = MessageDigest.getInstance("SHA-512");
//3. md를 이용해 암호화를 진행할 수 있도록 pw를 byte[]형태로 변환
byte[] bytes = pw.getBytes(Charset.forName("UTF-8"));
//4. 암호화 수행 -> 암호화 결과가 md 내부에 저장됨
md.update(bytes);
//5. 암호화된 비밀번호를 encryptPw에 대입
// byte[]을 Stirng으로 변환할 필요가 있음
// Base64 : byte 코드를 문자열로 변환하는 객체
encryptPw = Base64.getEncoder().encodeToString(md.digest());
System.out.println("암호화 전 : "+pw);
System.out.println("암호화 후 : "+encryptPw);
}catch(NoSuchAlgorithmException e) {
//SHA-512 해시 함수가 존재하지 않을때 예외 발생
e.printStackTrace();
}
return encryptPw;
}
}
3. DB
① 암호화된 비밀번호 원래 비밀번호로 세팅
UPDATE MEMBER
SET MEMBER_PW = 'aBN5hiegXlvAovJLipPoPd5LB+xjPrAeu1tcAVg0p5MKGocvo6l825SD+ZMCOcHBFeGB7MnzH31SAnDzYYsSdg=='
WHERE MEMBER_PW = 'pass01!';
--WHERE MEMBER_NO=1;
-- 업데이트 할 거면 COMMIT 해줘야한다!
COMMIT;
② 암호화된 비밀번호 크기가 크니 비밀번호 컬럼 크기 변경
( 테이블 구조 바꾸는 것은 ALTER)
ALTER TABLE MEMBER
MODIFY MEMBER_PW VARCHAR2(100);
-- ? 그럼 MEMBER_NO 1에 대한 건 암호화된 비밀번호를 다시 세팅했는데,
나머지 MEMBER에 대해헤사 전체를 다 업데이트 해야지 되는건가 (이건 다음시간에 확인하고 작성하겠다!)
'ON > Servlet' 카테고리의 다른 글
내 정보 수정하기 (0) | 2023.07.11 |
---|---|
내 정보 보기 (0) | 2023.07.10 |
Cookie / forward / Redirect 정리 (0) | 2023.07.10 |
[Servlet] 회원가입 만들기 (0) | 2023.07.09 |
servlet 공부하기 (0) | 2023.07.05 |