스프링 프레임워크/스프링 MVC

# Spring MVC 게시판 예제 12 : 계정 복구

edenDev 2023. 3. 5. 20:35

본 포스팅의 예제는 STS 또는 Eclipse를 사용하지 않고 Intellij를 통해 구현하고 있습니다.

그래서 기존의 STS(Spring Tool Studio)에서 생성된 Spring 프로젝트의 스프링 관련 설정 파일명과

프로젝트 구조가 약간 다를 수 있습니다.Intellij 스프링 mvc 프로젝트 생성 포스팅을 참고해주시면 감사하겠습니다.


Spring-MVC 기본 개념 및 테스트 예제 관련 포스팅 링크

순서 포스팅 제목
1 Intellij에서 Spring MVC Project 생성하기
2 Spring MVC - MariaDB 연결테스트
3 Spring MVC - Mybatis 설정 및 테스트
4 SpringMVC 구조
5 SpringMVC + Mybatis
6 Spring MVC Controller 작성 연습
7 Spring Interceptor

 

Spring-MVC 게시판 예제 이전 포스팅 링크

순서 포스팅제목
1 IntelliJ를 이용한 Spring MVC Project 생성 하기
2 Bootstrap AdminLTE Template 적용하기
3 ExceptionResovler : 예외페이지 처리
4 Spring AOP 적용하기
5 회원가입 구현하기
6 회원 유효성 검사 (Feat. JavaScript)
7 회원 유효성 검사 (Feat. Validation)
8 HttpSession을 이용한 로그인 구현하기
9 아이디 찾기 및 패스워드 찾기
10 내 프로필 페이지 및 회원정보 변경 및 탈퇴 구현
11 인터셉터 권한 체크 구현

1. 계정 복구 페이지 구현 하기

 

1.1 계정 복구 페이지 영속 계층(Persistence Tier) 구현 하기

 

src/기본패키지/user/persistence 패키지 안에 UserDAO 인터페이스와 UserDAOImpl 클래스 파일 두개에 아래와 같이 내용을 추가 해주세요.


//  아이디 체크
public int isCheckId(String user_id);

//  닉네임 체크
public int isCheckNickName(UserVo param);

//  이메일 체크
public int isCheckEmail(UserVo param);

//  계정 복구 정보 조회
public int checkUser(UserVo param);

//  계정 활성화
public void recoveryUserByInfo(UserVo param);

//  아이디 체크
public int isCheckId(String user_id) {
    return sqlSession.selectOne(NAMESPACE + ".isCheckId", user_id);
}

//  닉네임 체크
public int isCheckNickName(UserVo param) {
    return sqlSession.selectOne(NAMESPACE + ".isCheckNickName", param);
}

//  이메일 체크
public int isCheckEmail(UserVo param) {
    return sqlSession.selectOne(NAMESPACE + ".isCheckEmail", param);
}

//  계정 복구 정보 조회
public int checkUser(UserVo param) {
    return sqlSession.selectOne(NAMESPACE + ".checkUser", param);
}

//  계정 활성화
public void recoveryUserByInfo(UserVo param) {
    sqlSession.update(NAMESPACE + ".recoveryUserByInfo", param);
}

/resources/mappers/user 패키지 안에 UserSQLMapper.xml ㅍ파일 안에 아래와 같이 내용을 추가 해주세요


<!-- 아이디 체크 -->
<select id="isCheckId" resultType="int">
    select count(*) from eden_user where user_id = #{user_id}
</select>

<!-- 닉네임 체크 -->
<select id="isCheckNickName" resultType="int">
    select count(*) from eden_user where user_id = #{user_id} and user_nickname = #{user_nickname}
</select>

<!-- 이메일 체크 -->
<select id="isCheckEmail" resultType="int">
    select count(*) from eden_user where user_id = #{user_id} and user_email = #{user_email}
</select>

<!-- 계정 복구 데이터 조회 -->
<select id="checkUser" resultType="int">
    select *
    from eden_user
    where user_id = #{user_id}
      and user_nickname = #{user_nickname}
      and user_email = #{user_email}
</select>

<!-- 계정 활성화 -->
<update id="recoveryUserByInfo">
    update eden_user
    SET user_status = 'active'
    where user_id = #{user_id}
      and user_nickname = #{user_nickname}
      and user_email = #{user_email}
</update>

1.2 계정 복구 페이지 비지니스 계층(Business Tier) 구현

 

src/기본패키지/user/service 패키지 안에 UserService 인터페이스와 UserServiceImpl 클래스 파일에 아래와 같이 내용을 추가 해주세요


//  아이디 체크
public boolean isCheckId(String user_id);

//  닉네임 체크
public boolean isCheckNickName(UserVo param);

//  이메일 체크
public boolean isCheckEmail(UserVo param);

//  계정복구 정보 조회
public int checkUser(UserVo param);

//  계정 활성화
public void recoveryUserByInfo(UserVo param);

//  아이디 체크
@Override
@LogException
public boolean isCheckId(String user_id) {
    return userDAO.isCheckId(user_id) > 0;
}

//  닉네임 체크
@Override
@LogException
public boolean isCheckNickName(UserVo param) {
    return userDAO.isCheckNickName(param) > 0;
}

//  이메일 체크
@Override
@LogException
public boolean isCheckEmail(UserVo param) {
    return userDAO.isCheckEmail(param) > 0;
}

//  계정 복구 정보 조회
@Override
@LogException
public int checkUser(UserVo param) {
    return userDAO.checkUser(param);
}

//  계정 활성화
@Override
@LogException
public void recoveryUserByInfo(UserVo param) {
    userDAO.recoveryUserByInfo(param);
}

1.3 계정 복구 페이지 컨트롤러 구현

 

src/기본패키지/user/controller 패키지 안에 UserController 클래스와 RestUserController 클래스 파일의 내용을 아래와 같이 추가 해주세요.


//  계정복구 페이지
@GetMapping(value = "userRecoveryPage")
public String userRecoveryPage() {
    return "user/userRecoveryPage";
}

//  아이디 체크
@PostMapping(value = "checkId")
@LogException
public HashMap<String, Object> checkId(String user_id) {
    HashMap<String, Object> data = new HashMap<String, Object>();

    boolean isCheckId = userService.isCheckId(user_id);

    if (isCheckId) {
        data.put("result", "success");
    } else {
        data.put("result", "fail");
    }
    return data;
}

//  닉네임 체크
@PostMapping("checkNickName")
@LogException
public HashMap<String, Object> checkNickName(UserVo param) {

    HashMap<String, Object> data = new HashMap<String, Object>();

    boolean isCheckNick = userService.isCheckNickName(param);

    if (isCheckNick) {
        data.put("result", "success");
    } else {
        data.put("result", "fail");
    }
    return data;
}

//  이메일 체크
@PostMapping(value = "emailCheck")
@LogException
public HashMap<String, Object> emailCheck(UserVo param) {

    HashMap<String, Object> data = new HashMap<String, Object>();

    boolean isCheckNick = userService.isCheckEmail(param);

    if (isCheckNick) {
        data.put("result", "success");
        Random random = new Random();
        int checkNum = random.nextInt(888888) + 111111;

        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");

            messageHelper.setFrom("hanbyeols333z@gmail.com", "관리자"); // 보내는사람 이메일 여기선 google 메일서버 사용하는 아이디를 작성하면됨
            messageHelper.setTo(param.getUser_email()); // 받는사람 이메일
            messageHelper.setSubject("계정 복구 인증 메일입니다.."); // 메일제목
            messageHelper.setText("홈페이지를 방문해주셔서 감사합니다." +
                    "인증 번호는 " + checkNum + " 입니다." +
                    "\r\n" +
                    "해당 인증번호를 인증번호 확인란에 기입하여 주세요."); // 메일 내용

            javaMailSender.send(mimeMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }

        data.put("code", checkNum);
    } else {
        data.put("result", "fail");
    }
    return data;
}

//  계정복구
@PostMapping(value = "recoveryUserByInfo")
@LogException
public HashMap<String, Object> recoveryUserByInfo (UserVo vo){

    HashMap<String, Object> data = new HashMap<String, Object>();


    int checkUser = userService.checkUser(vo);

    if ( checkUser == 1 ) {
        userService.recoveryUserByInfo(vo);
        data.put("result", "success");
    } else {
        data.put("result", "fail");
    }

    return data;
}

1.4 계정 복구 페이지 JSP 구현

 

web-inf/views/user 패키지안에 userRecoveryPage.jsp 파일을 생성 한뒤 아래와 같이 내용을 작성 해주세요

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@ include file="../include/head.jsp" %>
<%@ include file="../include/user_menu.jsp" %>

<html>
<body class="hold-transition skin-green-light sidebar-mini" oncopy="return false" oncut="return false"
      onpaste="return false">
<div class="wrapper">

    <%@ include file="../include/top_menu.jsp" %>

    <%@ include file="../include/left_menu.jsp" %>

    <div class="content-wrapper">
        <section class="content container-fluid">
            <div class="row mt-3" id="submitOptionBox"> <!-- 옵션박스 -->
                <div class="col">
                    <div class="row mt-3">
                        <div class="col"><label for="userId">아이디</label></div>
                    </div>
                </div>

                <div class="row mt-1">
                    <div class="col-md-4">
                        <input class="form-control" id="userId" type="text" placeholder="아이디를 입력해 주세요." aria-label="default input example">
                    </div>
                    <div class="col-md-2"><button class="btn btn-info btn-sm" id="checkingId">아이디 체크</button></div>
                    <div class="col" id="checkId"></div>
                </div>

                <div class="row mt-3">
                    <div class="col">
                        <label for="userNick">
                            닉네임
                        </label>
                    </div>
                </div>

                <div class="row mt-1">
                    <div class="col-md-4">
                        <input class="form-control" id="userNick"  type="text" placeholder="닉네임을 입력해 주세요." aria-label="default input example" disabled="disabled">
                    </div>
                    <div class="col-md-2"><button class="btn btn-info btn-sm" id="checkingNickName" disabled="disabled">닉네임 체크</button></div>
                    <div class="col" id="checkNickName"></div>
                </div>

                <div class="row mt-3">
                    <div class="col">
                        <label for="userpw">비밀번호</label>
                    </div>
                </div>

                <div class="row mt-1">
                    <div class="col-md-4">
                        <input class="form-control" id="userpw"  type="password" placeholder="비밀번호를 입력해 주세요." aria-label="default input example" disabled="disabled">
                    </div>
                    <div class="col-md-2"><button class="btn btn-info btn-sm" id="checkingPw" disabled="disabled">비밀번호 체크</button></div>
                    <div class="col" id="checkPassword"></div>
                </div>

                <div class="row mt-3">
                    <div class="col">
                        <label for="Email">이메일주소</label>
                    </div>
                </div>

                <div class="row mt-1">
                    <div class="col-md-4">
                        <input type="text" id="Email" class="form-control" placeholder="이메일을 입력해주세요" disabled="disabled">
                    </div>
                    <div class="col-md-2">
                        <button type="button" id="checkButton"
                                class="btn btn-info btn-sm" disabled="disabled">인증번호 발송
                        </button>
                    </div>
                    <div class="col" id="checkEmail"></div>
                </div>

                <div class="row mt-3">
                    <div class="col">
                        <label for="authentication">인증번호</label>
                    </div>
                </div>

                <div class="row mt-1">
                    <div class="col-md-4">
                        <input type="text" id="authentication" class="form-control" placeholder="인증번호를 입력해주세요" disabled="disabled">
                    </div>
                    <div class="col-md-2">
                        <button type="button" id="authenticationButton"
                                class="btn btn-info btn-sm" disabled='disabled'>인증번호 확인
                        </button>
                    </div>
                    <div class="col" id="checkAuthentication"></div>
                </div>


                <div class="row mt-3">
                    <div class="col bi bi-exclamation-square-fill deepblue">&nbsp;돌아오신 것을 환영합니다! 정보를 정확히 기입하셔야 계정활성화가 가능합니다.</div>
                </div>

                <div class="row mt-3">
                    <div class="col">
                        <button type="button" id="recoveryButton" class="btn-info btn-sm pull-right" disabled='disabled'>&nbsp;계정활성화</button>
                    </div>
                </div>
            </div>
        </section>
    </div>

    <%@ include file="../include/footer.jsp" %>

</div>

<%@ include file="../include/plugin_js.jsp" %>
</body>
</html>

1.5  계정복구 페이지 JavaScript 구현

 

webapp/resources/dist/js/user 패키지 안에 relatedUser.js 파일에 아래의 내용을 추가 해주세요.


$("#checkingId").click(function () {
    if ($("#userId").val() == '') {
        alert("아이디를 먼저 입력해주세요");
        return;
    }

    $.ajax({
        type: "post",
        url: "../user/checkId",
        data:  {
            user_id: $("#userId").val()
        },
        dataType: "json",
        success: function (data) {
            if (data.result == 'fail') {
                $("#checkId").css({
                    "color": "red",
                    "font-size": "12px"
                });
                $("#checkId").text("!  아이디가 존재 하지 않습니다.");
            } else {
                $("#checkId").css({
                    "color": "green",
                    "font-size": "12px"
                });
                $("#checkId").text("✔  아이디가 존재 합니다.");
                $("#userNick").attr("disabled", false);
                $("#checkingNickName").attr("disabled", false);
                $("#checkingId").attr("disabled", true);
            }
        }
    });
});

$("#checkingNickName").click(function () {
    if ($("#userNick").val() == '') {
        alert("이메일을 먼저 입력해주세요");
        return;
    }

    $.ajax({
        type: "post",
        url: "../user/checkNickName",
        data: {
            user_id: $("#userId").val(),
            user_nickname: $("#userNick").val()
        },
        dataType: "json",
        success: function (data) {
            if (data.result == 'fail') {
                $("#checkNickName").css({
                    "color": "red",
                    "font-size": "12px"
                });
                $("#checkNickName").text("!  가입 당시 입력하신 닉네임이 아닙니다 다시 확인해주세요");
            } else {
                $("#checkNickName").css({
                    "color": "green",
                    "font-size": "12px"
                });
                $("#checkNickName").text("✔  닉네임이 일치 합니다.");
                $("#userpw").attr("disabled", false);
                $("#checkingPw").attr("disabled", false);
                $("#checkingNickName").attr("disabled", true);
            }
        }
    });
});

$("#checkingPw").click(function () {
    if ($("#userpw").val() == '') {
        alert("비밀번호를 먼저 입력해주세요");
        return;
    }

    $.ajax({
        type: "post",
        url: "../user/checkPw",
        data: {
            user_id: $("#userId").val(),
            current_password: $("#userpw").val()
        },
        dataType: "json",
        success: function (data) {
            if (data.result == 'fail') {
                $("#checkPassword").css({
                    "color": "red",
                    "font-size": "12px"
                });
                $("#checkPassword").text("!  현재 비밀번호와 일치 하지 않습니다.");
            } else {
                $("#checkPassword").css({
                    "color": "green",
                    "font-size": "12px"
                });
                $("#checkPassword").text("✔  현재 비밀번호와 일치 합니다.");
                $("#checkingPw").attr("disabled", true);
                $("#Email").attr("disabled", false);
                $("#checkButton").attr("disabled", false);
            }
        }
    });
});

var code;

$("#checkButton").click(function () {
    if ($("#Email").val() == '') {
        alert("이메일을 먼저 입력해주세요");
        return;
    }
    $.ajax({
        type: "post",
        url: "../user/emailCheck",
        data: {
            user_id: $("#userId").val(),
            user_email: $("#Email").val()
        },
        dataType: "json",
        success: function(data) {
            if (data.result == 'fail') {
                $("#checkEmail").css({
                    "color": "red",
                    "font-size": "12px"
                });
                $("#checkEmail").text("!  현재 이메일과 일치 하지 않습니다.");
            } else {
                $("#checkEmail").css({
                    "color": "green",
                    "font-size": "12px"
                });
                $("#checkEmail").text("✔  현재 이메일과 일치 합니다.");
                alert("인증번호 발송이 완료되었습니다. 입력한 이메일에서 인증번호 확인을 해주세요.");
                $("#authentication").attr("disabled", false);
                $("#authenticationButton").attr("disabled", false);
                $("#checkButton").attr("disabled", true);
                code = data.code;
            }
        }
    });
});

$("#authenticationButton").click(function () {
    if ($("#authentication").val() == '') {
        $("#checkAuthentication").css({
            "color": "green",
            "font-size": "12px"
        });
        $("#checkAuthentication").text("!  인증번호를 먼저 입력해주세요");
        return;
    }

    if (code == $("#authentication").val()) {
        $("#checkAuthentication").css({
            "color": "green",
            "font-size": "12px"
        });
        $("#checkAuthentication").text("✔  메일 인증이 완료 되었습니다.");
        $("#authenticationButton").attr("disabled", true);
        $("#authentication").attr("disabled", true);
        $("#recoveryButton").attr("disabled", false);
    }
});

$("#recoveryButton").click(function () {
    $.ajax({
        type: "post",
        url: "../user/recoveryUserByInfo",
        data: {
            user_id: $("#userId").val(),
            user_nickname: $("#userNick").val(),
            user_email: $("#Email").val()
        },
        dataType: "json",
        success: function (data) {
            if (data.result == 'fail') {
                alert("해당하는 유저 정보가 없습니다 다시 확인해주세요");
            } else {
                alert("계정 복구에 성공 하였습니다.")
                location.href = "/";
            }
        }
    });
});

1.6 계정 복구페이지 화면 확인


2. 정리

 

이번에는 계정 복구 페이지를 구현 해보았습니다. 다음에는 인터셉터와 쿠키를 활용하여 자동로그인 을 구현 해보도록 하겠습니다.