국비 84 - 회원탈퇴(스프링)

냐아암·2023년 8월 16일
0

국비

목록 보기
97/114

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"  %>

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>My Page</title>

    <link rel="stylesheet" href="/resources/css/myPage/myPage-style.css">

</head>
<body>
    <main>
       <jsp:include page="/WEB-INF/views/common/header.jsp"/>

        
        <!-- 마이페이지 - 내 정보 -->
        <section class="myPage-content">
            
			<!-- 사이드메뉴 include -->
			<!-- jsp 액션 태그 -->
			<jsp:include page="/WEB-INF/views/myPage/sideMenu.jsp"/>


            <!-- 오른쪽 마이페이지 주요 내용 부분 -->
            <section class="myPage-main">

                <h1 class="myPage-title">회원 탈퇴</h1>
                <span class="myPage-subject">현재 비밀번호가 일치하는 경우 탈퇴할 수 있습니다.</span>

                <form action="secession" method="POST" name="myPageFrm">

                    <div class="myPage-row">
                        <label>비밀번호</label>
                        <input type="password" name="memberPw" id="memberPw" maxlength="30">              
                    </div>

                    
                    <div class="myPage-row info-title">
                        <label>회원 탈퇴 약관</label>
                    </div>

                    <pre class="secession-terms">
제1조
이 약관은 샘플 약관입니다.

① 약관 내용 1

② 약관 내용 2

③ 약관 내용 3

④ 약관 내용 4


제2조
이 약관은 샘플 약관입니다.

① 약관 내용 1

② 약관 내용 2

③ 약관 내용 3

④ 약관 내용 4

                    </pre>

                    <div>
                        <input type="checkbox" name="agree" id="agree">
                        <label for="agree">위 약관에 동의합니다.</label>
                    </div>


                    <button class="myPage-submit">탈퇴</button>

                </form>

            </section>

        </section>

    </main>

	<jsp:include page="/WEB-INF/views/common/footer.jsp"/>

</body>
</html>
// 내 정보(수정)페이지

const memberNickname = document.getElementById("memberNickname");
const memberTel = document.getElementById("memberTel");
const updateInfo = document.getElementById("updateInfo");

// 내 정보 수정 form 태그가 존재할 때(내 정보 페이지)
if(updateInfo != null){

    // 전역 변수로 수정 전 닉네임/전화번호를 저장
    initNickname = memberNickname.value;
    initTel = memberTel.value;


    // 닉네임 유효성 검사
    memberNickname.addEventListener("input", () => {

        // 변경 전 닉네임과 입력값이 같을 경우
        if(initNickname == memberNickname.value){
            memberNickname.removeAttribute("style");
            return;
        }

        // 정규 표현식으로 유효성 검사
        const regEx = /^[가-힣\d\w]{2,10}$/;

        if(regEx.test(memberNickname.value)){
            memberNickname.style.color="green"
        } else {
            memberNickname.style.color="red"
        }

    });

    // 전화번호 유효성 검사
    memberTel.addEventListener("input", () => {

        // 변경 전 전화번호와 입력 값이 같을 경우
        if(initTel == memberTel.value){
            memberTel.removeAttribute("style");
            return;
        }

        // 정규 표현식으로 유효성 검사
        const regEx = /^0(1[01679]|2|[3-6][1-5]|70)\d{3,4}\d{4}$/;
        if(regEx.test(memberTel.value)){
            memberTel.style.color="green";
        } else {
            memberTel.style.color="red";
        }

    });

    // form 태그 제출 시 유효하지 않은 값이 있으면 제출 X
    updateInfo.addEventListener("submit" ,e => {

        // 닉네임이 유효하지 않은 경우
        if(memberNickname.style.color == "red"){
            alert("닉네임이 유효하지 않습니다.");
            memberNickname.focus();
            
            e.preventDefault();
            return;
        }

        // 전화번호가 유효하지 않은 경우
        if(memberTel.style.color == "red"){
            alert("전화번호가 유효하지 않습니다.");
            memberTel.focus();
            
            e.preventDefault();
            return;
        }

    })
} // if문 끝*-

// 비밀번호 변경 제출 시 
const changePwFrm = document.getElementById("changePwFrm");
const currentPw = document.getElementById("currentPw");
const newPw = document.getElementById("newPw");
const newPwConfirm = document.getElementById("newPwConfirm");

// 비밀번호 변경 페이지인 경우
if(changePwFrm != null){

    changePwFrm.addEventListener("submit", e => {

        // 현재 비밀번호 미작성 시
        if(currentPw.value.trim() == ""){
            alert("현재 비밀번호를 입력해주세요");
            e.preventDefault();
            currentPw.focus();
            currentPw.value = "";
            return;
        }

        // 비밀번호 유효성 검사
        const regEx = /^[A-Za-z\d\!\@\#\-\_]{6,20}$/;

        if(!regEx.test(newPw.value)){
            alert("비밀번호가 유효하지 않습니다.");
            e.preventDefault();
            newPw.focus();
            newPw.value = "";
            return;
        }

        if(newPw.value != newPwConfirm.value ){
            alert("비밀번호가 일치하지 않습니다.");
            e.preventDefault();
            newPwConfirm.focus();
            newPwConfirm.value = "";
            return;
        }


    })

} // if문 끝

// 회원탈퇴
const secessionFrm = document.getElementById("secessionFrm");
const memberPw = document.getElementById("memberPw");
const agree = document.getElementById("agree");

// 회원탈퇴 페이지인 경우
if(secessionFrm != null){

    secessionFrm.addEventListener("submit", e => {

        // 비밀번호 미작성
        if(memberPw.value.trim() == ""){
            alert("비밀번호를 입력해주세요");
            e.preventDefault();
            memberPw.focus();
            memberPw.value = "";
            return;
        }

        // 동의 체크가 되지 않은 경우
        if(!agree.checked){
            alert("약관 동의 후 탈퇴 버튼을 눌러주세요");
            e.preventDefault();
            agree.focus();
            return;
        }

        // 취소 클릭 시
        if(!confirm("정말 탈퇴하시겠습니까?")){
            alert("탈퇴 취소");
            e.preventDefault();
            return;
        }

    });


}

🔑 쿠키 삭제 주의

MyPageController

// 회원 탈퇴
	@PostMapping("/secession")
	public String secession(String memberPw, @SessionAttribute("loginMember") Member loginMember
							, SessionStatus status, HttpServletResponse resp, RedirectAttributes ra) {
		
		// String memberPw : 입력한 비밀번호 
		// SessionStatus status : session을 관리하는 객체
		// HttpServletResponse resp : 서버 -> 클라이언트 응답하는 방법 제공 객체
		// RedirectAttributes ra : 리다이렉트 시 request로 값 전달하는 객체
		
		// 1. 로그인한 회원 번호 얻어오기
		// @SessionAttribute("loginMember") Member loginMember
		int memberNo = loginMember.getMemberNo();
		
		// 2. 회원 탈퇴 service 호출
		// - 비번 일치하면 MEMBER_DEL_FL -> Y로 바꾸고 1 반환
		// - 비번 일치하지 않으면 0 반환
		int result = service.secession(memberPw, memberNo);
		
		
		String path = "redirect:";
		String message = null;
		
		if(result>0) { // 3. 탈퇴 성공 시
			
			// - 로그아웃
			status.setComplete();
			
			// + 쿠키 삭제
			Cookie cookie = new Cookie("saveId", "");
			// 같은 쿠키가 이미 존재하면 덮어쓰기 된다.
			
			cookie.setMaxAge(0); // 0초 생존 -> 삭제
			
			cookie.setPath("/"); // 요청 시 쿠키가 첨부되는 경로 지정
			
			resp.addCookie(cookie); // 요청 객체를 통해서 클라이언트에게 전달
									// -> 클라이언트 컴퓨터에 파일로 생성
			
			// - message : 탈퇴되었습니다
			message = "탈퇴되었습니다.";
			
			// - 메인페이지로 redirect
			path += "/";
			
			
		} else { // 4. 탈퇴 실패 시
			
			// - message : 현재 비밀번호가 일치하지 않습니다.
			message = "현재 비밀번호가 일치하지 않습니다.";
			
			// - 회원 탈퇴 페이지로 redirect
			path += "secession";
		}
		
		ra.addFlashAttribute("message", message);
		
		return path;
	}

MyPageService

/** 회원 탈퇴 서비스
	 * @param memberPw
	 * @param memberNo
	 * @return result
	 */
	int secession(String memberPw, int memberNo);

MyPageServiceImpl

// 회원 탈퇴
	@Transactional(rollbackFor = {Exception.class})
	@Override
	public int secession(String memberPw, int memberNo) {
		
		// 회원번호 일치하는 회원의 비밀번호 조회
		String encPw = dao.selectEncPw(memberNo);
		
		// 비밀번호 일치하면
		if(bcrypt.matches(memberPw, encPw)) {
			// MEMBER_DEL_FL -> 'Y'로 바꾸고 1 반환
			return dao.secession(memberNo);
		}
		
		return 0;
	}
    

MyPageDAO

/** 회원 탈퇴
	 * @param memberNo
	 * @return result
	 */
	public int secession(int memberNo) {
		// sqlSessionTemplate : 마이바티스 + DBCP + close 자동 + 트랜잭션 처리
		return sqlSession.update("myPageMapper.secession", memberNo);
	}
    

SQL

<!-- 회원 탈퇴 -->
	<update id="secession" parameterType="_int">
		UPDATE MEMBER SET MEMBER_DEL_FL='Y' WHERE MEMBER_NO = #{memberNo}
	</update>
    
profile
개발 일지

0개의 댓글