[Spring] 관리자 로그인

2023. 12. 20. 23:16공부 중/웹프로그래밍 (Spring)

0. 출처

아직 배우고 있는 중이라 부정확한 정보가 포함되어 있을 수 있습니다!
주의하세요!

올인원 스프링 프레임워크 참고.

 

올인원 스프링 프레임워크 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

 


1. 로그인 화면

 

이전에 관리자 회원가입 기능을 구현했다.

 

최고 관리자가 아닌 일반 관리자의 경우 회원가입 후 최고 관리자의 승인 이후에 로그인이 가능하다.

 

관리자 목록을 출력하고 로그인을 승인하는 기능을 구현하고 로그인까지 구현해 보자.

 

<li><a href="<c:url value='/admin/member/loginForm' />">로그인</a></li>

admin/include/nav.jsp를 보면 로그인 버튼을 누르면 클라이언트에서 보내는 url을 알 수 있다.

 

@Controller
@RequestMapping("/admin/member")
public class AdminMemberController {
    ...

    @GetMapping("/loginForm")
    public String loginForm() {
        System.out.println("[AdminMemberController] loginForm()");

        String nextPage = "admin/member/login_form";

        return nextPage;
    }
}

AdminMemberController/admin/member/loginForm 에 대한 HTTP GET 요청을 처리하는 Method를 추가한다.

 

 

/admin/member/loginForm 로그인 화면이다.

 

<%@ 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>
<head>
<meta charset="UTF-8">

<jsp:include page="../../include/title.jsp" />

<link href="<c:url value='/resources/css/admin/login_form.css' />" rel="stylesheet" type="text/css">

<jsp:include page="../include/login_js.jsp" />

</head>
<body>

    <jsp:include page="../../include/header.jsp" />

    <jsp:include page="../include/nav.jsp" />

    <section>

        <div id="section_wrap">

            <div class="word">

                <h3>LOGIN FORM</h3>

            </div>

            <div class="login_form">

                <form action="<c:url value='/admin/member/loginConfirm' />" name="login_form" method="post">

                    <input type="text"        name="a_m_id"         placeholder="INPUT ADMIN ID."> <br>
                    <input type="password"    name="a_m_pw"         placeholder="INPUT ADMIN PW."> <br>
                    <input type="button"    value="login" onclick="loginForm();"> 
                    <input type="reset"        value="reset">

                </form>

            </div>

            <div class="find_password_create_account">

                <a href="<c:url value='/admin/member/findePasswordForm' />">find password</a>
                <a href="<c:url value='/admin/member/createAccountForm' />">create account</a>

            </div>

        </div>

    </section>

    <jsp:include page="../../include/footer.jsp" />

</body>
</html>

WEB-INF/views/admin/member/login_form.jsp이다.

 

...
<form action="<c:url value='/admin/member/loginConfirm' />" name="login_form" method="post">
    <input type="text"        name="a_m_id"         placeholder="INPUT ADMIN ID."> <br>
    <input type="password"    name="a_m_pw"         placeholder="INPUT ADMIN PW."> <br>
    <input type="button"    value="login" onclick="loginForm();"> 
    <input type="reset"        value="reset">
</form>

아이디 정보를 a_m_id으로, 비밀번호를 a_m_pw라는 이름으로 서버에 전송한다.

 

서버로 /admin/member/loginConfirm url로 POST 요청을 보낸다.

 


2. 로그인 기능 구현

 

클라이언트로부터 받은 /admin/member/loginConfirm 요청을 처리해 보자.

 


가. 컨트롤러

@Controller
@RequestMapping("/admin/member")
public class AdminMemberController {

    ...

    @PostMapping("/loginConfirm")
    public String loginConfirm(AdminMemberVo adminMemberVo) {
        System.out.println("[AdminMemberController] loginConfirm()");

        String nextPage = "admin/member/login_ok";

        AdminMemberVo loginedAdminMemberVo = adminMemberService.loginConfirm(adminMemberVo);

        if(loginedAdminMemberVo == null) {
            nextPage = "admin/member/login_ng";
        }

        return nextPage;
    }
}

AdminMemberController/admin/member/loginConfirm POST 요청을 처리하는 loginConfirm() 추가한다.

 

adminMemberService.loginConfirm(adminMemberVo);의 리턴값에 따라서 다른 view 정보를 반환한다.

 

loginedAdminMemberVonull이면 로그인에 실패한 것이다.

 


나. 서비스

@Service
public class AdminMemberService {
    ...

    public AdminMemberVo loginConfirm(AdminMemberVo adminMemberVo) {
        System.out.println("[AdminMemberService] loginConfirm()");

        AdminMemberVo loginedAdminMemberVo = adminMemberDao.selectAdmin(adminMemberVo);

        if(loginedAdminMemberVo != null)
            System.out.println("[AdminMemberService] ADMIN MEMBER LOGIN SUCCESS!!");
        else
            System.out.println("[AdminMemberService] ADMIN MEMBER LOGIN FAIL!!");

        return loginedAdminMemberVo;
    }
}

AdminMemberService.loginConfirm()에서는 AdminMemberController에게서 로그인 정보를 전달받아서 올바른 접근인지 확인한다.

 


다. DAO

@Component
public class AdminMemberDao {

    ...

    public AdminMemberVo selectAdmin(AdminMemberVo adminMemberVo) {
        System.out.println("[AdminMemberDao] selectAdmin()");

        String sql = "SELECT * FROM tbl_admin_member " + "WHERE a_m_id = ? AND a_m_approval > 0";

        List<AdminMemberVo> adminMemberVos = new ArrayList<AdminMemberVo>();

        try {
            adminMemberVos = jdbcTemplate.query(sql, new RowMapper<AdminMemberVo>() {
                @Override
                public AdminMemberVo mapRow(ResultSet rs, int rowNum) throws SQLException {
                    AdminMemberVo adminMemberVo = new AdminMemberVo();

                    adminMemberVo.setA_m_no(rs.getInt("a_m_no"));
                    adminMemberVo.setA_m_approval(rs.getInt("a_m_approval"));
                    adminMemberVo.setA_m_id(rs.getString("a_m_id"));
                    adminMemberVo.setA_m_pw(rs.getString("a_m_pw"));
                    adminMemberVo.setA_m_name(rs.getString("a_m_name"));
                    adminMemberVo.setA_m_gender(rs.getString("a_m_gender"));
                    adminMemberVo.setA_m_part(rs.getString("a_m_part"));
                    adminMemberVo.setA_m_position(rs.getString("a_m_position"));
                    adminMemberVo.setA_m_mail(rs.getString("a_m_mail"));
                    adminMemberVo.setA_m_phone(rs.getString("a_m_phone"));
                    adminMemberVo.setA_m_reg_date(rs.getString("a_m_reg_date"));
                    adminMemberVo.setA_m_mod_date(rs.getString("a_m_mod_date"));

                    return adminMemberVo;
                }

            }, adminMemberVo.getA_m_id());

            if(!passwordEncoder.matches(adminMemberVo.getA_m_pw(), adminMemberVos.get(0).getA_m_pw()))
                adminMemberVos.clear();

        } catch (Exception e) {
            e.printStackTrace();
        }

        return adminMemberVos.size() > 0 ? adminMemberVos.get(0) : null;
    }
}

데이터베이스에 전달받은 id와 같은 데이터를 찾고 비밀번호를 확인한다.

 

  • List<AdminMemberVo> adminMemberVos = new ArrayList<AdminMemberVo>();
    : SQL의 결괏값이 여러 개일 수 있음.

  • String sql = "SELECT * FROM tbl_admin_member " + "WHERE a_m_id = ? AND a_m_approval > 0";
    : 전달받은 아이디와 동일한 데이터를 데이버베이스로부터 조회한다.
    : 최고 관리자의 승인을 받아야 로그인할 수 있다.

  • if(!passwordEncoder.matches(adminMemberVo.getA_m_pw(), adminMemberVos.get(0).getA_m_pw())) adminMemberVos.clear();
    : 해쉬화된 비밀번호와 비교하여 올바른 비밀번호를 입력했는지 확인한다.

  • return adminMemberVos.size() > 0 ? adminMemberVos.get(0) : null;
    : 로그인에 성공하면 AdminMemberVo를 반환한다.
    : 로그인에 실패하면 null을 반환한다.

 

1) RowMapper

SELECT문을 실행하기 위해서 jdbcTemplate.query()을 사용해야 한다.

 

이때 query(String sql, RowMapper rowMapper)는 주어진 SQL문의 결과를 객체로 매핑해야 한다.

 

결괏값을 매핑하는 기능을 구현하기 위해선 RowMapper.mapRow()라는 추상 메서드를 구현해야 한다.

 

  • public [return type] mapRow(ResultSet rs, int rowNum)
    : rs는 SQL의 결괏값이 저장된 데이터셋이다.
    : rowNumrs 중 몇 번째 값을 매핑하고 있는지 나타낸다.

 

여기서는 adminMemberVo의 setter를 사용해서 데이터를 매핑한다.

 

매핑이 마무리되면 데이터가 저장된 adminMemberVo를 반환한다.

 


라. 로그인 시도

최고 관리자 로그인 성공.

 

일반 관리자 admin1을 생성한다.

 

 

일반 관리자 로그인 실패.

 

일반 관리자는 최고 관리자의 승인이 있어야지 로그인이 가능하다.

 

미승인 관리자의 경우 tbl_admin_member 테이블을 보면 a_m_approval이 0인 것을 볼 수 있다.

 


3. 로그인 상태 유지 & 로그아웃 구현

 

로그인 상태를 유지하는 기능을 구현한다.

 

이전에 Node.js에서 공부한 내용을 정리한 글.

 

 

[Node.js] 쿠키의 한계

1. 인증 부분의 한계 민감한 정보를 클라이언트 쪽에 저장한다는 것은 위험하다. 또한 쿠키는 쉽게 탈취당할 수 있기 때문에 민감한 정보를 저장하는 것에 어울리지 않는다. 그렇기 때문에 요즘

ramen4598.tistory.com

 

 

[Express] Session이란?

1. 세션 앞서 쿠키를 사용해서 인증을 구현하면 생기는 문제점에 대하여 알아보았다. [Node.js] 쿠키의 한계 1. 인증 부분의 한계 민감한 정보를 클라이언트 쪽에 저장한다는 것은 위험하다. 또한

ramen4598.tistory.com

 


가. 쿠키와 세션

 

웹 서버의 부하를 줄이기 위해서 HTTP 프로트콜은 비연결성 프로토콜이다.

 

 

연결을 유지하지 않기 때문에 HTTP는 클라이언트와 서버의 상태를 유지하지 않는 Stateless 한 특성을 지닌다.

 

로그인 상태를 유지하기 위해서 쿠키, 세션, JWT와 같은 기술을 사용한다.

 


1) 쿠키 실습

package com.company.cookie;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/member")
public class MemberComtroller {

    ...

    @PostMapping("/loginConfirm")
    public String loginConfirm(@RequestParam("m_id") String m_id, @RequestParam("m_pw") String m_pw, HttpServletResponse response) {
        System.out.println("[MemberController] loginConfirm()");

        String nextPage = "member/login_ok";

        if(m_id.equals("user") && m_pw.equals("1234")) {
            Cookie cookie = new Cookie("loginMember", m_id);
            cookie.setMaxAge(60 * 30);
            response.addCookie(cookie);
        }else {
            nextPage = "member/login_ng";
        }
        return nextPage;
    }

    @GetMapping("/logoutForm")
    public String logoutForm(@CookieValue(value = "loginMember", required = false) String loginMember, HttpServletResponse response) {
        System.out.println("[MemberController] logoutForm()");

        String nextPage = "redirect:/member";

        Cookie cookie = new Cookie("loginMember", loginMember);
        cookie.setMaxAge(0);

        response.addCookie(cookie);

        return nextPage;
    }
}

쿠키를 생성하고 쿠키를 제거하는 간단한 예시다.

 

  • Cookie cookie = new Cookie("loginMember", m_id);
    : 새로운 쿠키를 생성한다.
    : 이름은 loginMember, 값은 m_id의 값을 대입한다.

  • cookie.setMaxAge(60 * 30);
    : 쿠키의 유효 시간을 설정한다.
    : 시간의 기본 단위는 초다. (60 * 30 * 1초 = 30분)

  • cookie.setMaxAge(0);
    : 쿠키의 유효 시간을 0으로 설정한다.

  • response.addCookie(cookie);
    : 쿠키를 클라이언트에게 전달.

  • public String logoutForm(@CookieValue(value = "loginMember", required = false) String loginMember, HttpServletResponse response) {
    : 서버에서 쿠키를 전달받는 방법.
    : value는 사용할 쿠키의 이름을 입력한다.
    : required는 필수 요소인지 표시한다. false면 없어도 에레가 발생하지 않음.
    : 쿠키의 값은 String 타입으로 loginMember에 저장된다.

 


2) 세션

 

AdminMemberDao.selectAdmin()에선 로그인에 성공하면 계정의 정보가 담긴 AdminMemberVo를 반환하는데 이를 세션에 저장해 보겠다.

//AdminMemberController.java
...
@PostMapping("/loginConfirm")
public String loginConfirm(AdminMemberVo adminMemberVo, HttpSession session) {
    System.out.println("[AdminMemberController] loginConfirm()");

    String nextPage = "admin/member/login_ok";

    AdminMemberVo loginedAdminMemberVo = adminMemberService.loginConfirm(adminMemberVo);

    if(loginedAdminMemberVo == null) {
        nextPage = "admin/member/login_ng";
    }else {
        session.setAttribute("loginedAdminMemberVo", loginedAdminMemberVo);
        session.setMaxInactiveInterval(60 * 30);
    }

    return nextPage;
}

AdminMemberController에서 세션에 AdminMemberVo를 저장하도록 loginConfirm()를 수정한다.

 

  • public String loginConfirm(AdminMemberVo adminMemberVo, HttpSession session) { … }
    : loginConfirm()의 매개변수에 HttpSession 추가.
    : 요청을 보낸 클라이언트의 세션에 접근할 수 있음.

  • session.setAttribute("loginedAdminMemberVo", loginedAdminMemberVo);
    : setAttribute(String name, Object value) : void
    : 타입이 Object이기 때문에 모든 데이터 타입을 저장 가능.
    : 세션에 loginedAdminMemberVo이란 이름으로 loginAdminMemberVo 저장

  • session.setMaxInactiveInterval(60 * 30);
    : 기본 단위 초. (60 * 30 * 초 = 30분)
    : 설정한 시간 동안 아무런 동작이 없으면 세션이 종료되고 다시 로그인해야 함.

 

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

<link href="<c:url value='/resources/css/admin/include/nav.css' />" rel="stylesheet" type="text/css">

<jsp:include page="./nav_js.jsp" />

<nav>

    <div id="nav_wrap">

        <%
        AdminMemberVo loginedAdminMemberVo = (AdminMemberVo) session.getAttribute("loginedAdminMemberVo");
        if (loginedAdminMemberVo != null) {
        %>

        <div class="menu">
            <ul>
                <li><a href="<c:url value='/admin/member/logoutConfirm' />">로그아웃</a></li>
                <li><a href="<c:url value='/admin/member/modifyAccountForm' />">계정수정</a></li>

                <c:if test="${loginedAdminMemberVo.a_m_id eq 'super admin'}">
                    <li><a href="<c:url value='/admin/member/listupAdmin' />">관리자목록</a></li>
                </c:if>

                <li><a href="<c:url value='/book/admin/getRentalBooks' />">대출도서</a></li>
                <li><a href="<c:url value='/book/admin/getAllBooks' />">전체도서</a></li>
                <li><a href="<c:url value='/book/admin/getHopeBooks' />">희망도서(입고처리)</a></li>
                <li><a href="<c:url value='/book/admin/registerBookForm' />">도서등록</a></li>
            </ul>
        </div>
        <%
        } else {
        %>
        <div class="menu">
            <ul>
                <li><a href="<c:url value='/admin/member/loginForm' />">로그인</a></li>
                <li><a href="<c:url value='/admin/member/createAccountForm' />">회원가입</a></li>
            </ul>
        </div>
        <%
        }
        %>

        <div class="search">

            <form action="<c:url value='/book/admin/searchBookConfirm' />" name="search_book_form" method="get">
                <input type="text" name="b_name" placeholder="Enter the name of the book you are looking for.">
                <input type="button" value="search" onclick="searchBookForm();">
            </form>

        </div>
    </div>

</nav>

admin/include/nav.jsp에서 세션의 loginAdminMemberVo 속성값이 null인지 아닌지 확인한다.

 

null이면 로그인, 회원가입 링크를, null이 아니면 로그아웃, 계정수정, 관리자목록 등 링크를 보여준다.

 

 

 


나. 로그아웃

//AdminMemberController.java
...
@GetMapping("/logoutConfirm")
public String logoutConfirm(HttpSession session) {
    System.out.println("[AdminMemberController] logoutConfirm()");

    String nextPage = "redirect:/admin";

    session.invalidate();

    return nextPage;
}

AdminMemberControllerlogoutConfirm() 추가.

 

  • String nextPage = "redirect:/admin";
    : /admin으로 리다이렉트

  • session.invalidate();
    : 세션 무효화.
    : 세션에 저장된 데이터(예: 사용자 인증 정보, 사용자 설정 등)가 모두 삭제.
    : 서버에 할당된 자원을 해제. 불필요한 메모리 사용을 줄이는 데 도움이 됨.

 

1) 주요 HttpSession 기능

메서드 목적 설명
getId() 세션 ID 획득 현재 HTTP 세션의 고유 식별자를 반환합니다.
getAttribute(String name) 속성 조회 지정된 이름의 객체를 세션에서 반환합니다.
setAttribute(String name, Object value) 속성 설정 세션에 객체를 저장합니다. 이름과 값으로 구성됩니다.
removeAttribute(String name) 속성 제거 세션에서 지정된 이름의 객체를 제거합니다.
invalidate() 세션 무효화 현재 세션을 종료하고, 모든 속성을 제거합니다.
isNew() 새 세션 확인 현재 세션 객체가 새로 생성되었는지 여부를 반환합니다.
setMaxInactiveInterval(int second) 최대 비활성화 간격 설정 세션의 최대 비활성화 시간(초 단위)을 설정합니다.
getMaxInactiveInterval() 최대 비활성화 간격 조회 세션의 최대 비활성화 시간을 반환합니다.
getCreationTime() 생성 시간 조회 세션 생성 시간을 반환합니다.
getLastAccessedTime() 마지막 접근 시간 조회 세션에 마지막으로 접근한 시간을 반환합니다.

 


4. 최고 관리자 승인 처리 기능 구현

 

최고 관리자가 일반 관리자 목록을 조회하고 특정 일반 관리자의 로그인을 승인하는 기능을 구현해 보자.

 


가. 관리자 목록 조회하기

 

1) 컨트롤러

@RequestMapping(value="/listupAdmin", method = RequestMethod.GET)
public String listupAdmin(Model model) {
    System.out.println("[AdminMemberController] listupAdmin()");

    String nextPage = "admin/member/listup_admins";

    List<AdminMemberVo> adminMemberVos = adminMemberService.listupAdmin();

    model.addAttribute("adminMemberVos", adminMemberVos);

    return nextPage;
}

관리자 목록을 조회하는 /admin/member/listupAdmin 요청을 처리한다.

  • model.addAttribute("adminMemberVos", adminMemberVos);
    : 뷰(admin/member/listup_admins)에 전달할 데이터를 model에 저장한다.

 


2) 서비스

public List<AdminMemberVo> listupAdmin() {
    System.out.println("[AdminMemberService] listupAdmin()");

    return adminMemberDao.selectAdmins();
}

AdminMemberService.listupAdmin() 선언.

 


3) DAO

public List<AdminMemberVo> selectAdmins() {
    // TODO Auto-generated method stub
    System.out.println("[AdminMemberDao] selectAdmins()");

    String sql = "SELECT * FROM tbl_admin_member";

    List<AdminMemberVo> adminMemberVos = new ArrayList<AdminMemberVo>();

    try {
        adminMemberVos = jdbcTemplate.query(sql, new RowMapper<AdminMemberVo>() {
            @Override
            public AdminMemberVo mapRow(ResultSet rs, int rowNum) throws SQLException{
                AdminMemberVo adminMemberVo = new AdminMemberVo();

                adminMemberVo.setA_m_no(rs.getInt("a_m_no"));
                adminMemberVo.setA_m_approval(rs.getInt("a_m_approval"));
                adminMemberVo.setA_m_id(rs.getString("a_m_id"));
                adminMemberVo.setA_m_pw(rs.getString("a_m_pw"));
                adminMemberVo.setA_m_name(rs.getString("a_m_name"));
                adminMemberVo.setA_m_gender(rs.getString("a_m_gender"));
                adminMemberVo.setA_m_part(rs.getString("a_m_part"));
                adminMemberVo.setA_m_position(rs.getString("a_m_position"));
                adminMemberVo.setA_m_mail(rs.getString("a_m_mail"));
                adminMemberVo.setA_m_phone(rs.getString("a_m_phone"));
                adminMemberVo.setA_m_reg_date(rs.getString("a_m_reg_date"));
                adminMemberVo.setA_m_mod_date(rs.getString("a_m_mod_date"));

                return adminMemberVo;
            }
        });
    }catch (Exception e) {
        e.printStackTrace();
    }

    return adminMemberVos;
}
  • String sql = "SELECT * FROM tbl_admin_member";
    : 모든 관리자 정보를 조회.

 


4) 뷰

/BookRentalPjt/src/main/webapp/WEB-INF/views/admin/member/listup_admins.jsp 참고

...

<c:forEach var="item" items="${adminMemberVos}">
    <tr>
        <td>${item.a_m_id}</td>
        <td>${item.a_m_name}</td>
        <td>${item.a_m_gender}</td>
        <td>${item.a_m_part}</td>
        <td>${item.a_m_position}</td>
        <td>${item.a_m_mail}</td>
        <td>${item.a_m_phone}</td>
        <td>
            <c:choose>
                <c:when test="${item.a_m_approval eq 0}">
                    <c:url value='/admin/member/setAdminApproval' var='approval_url'>
                        <c:param name='a_m_no' value='${item.a_m_no}'/>
                    </c:url>
                    <a href="${approval_url}">승인처리</a>
                </c:when>
                <c:when test="${item.a_m_approval eq 1}"> <c:out value="승인완료" /> </c:when>
            </c:choose>
        </td>
    </tr>
</c:forEach>
  • <c:when test="${item.a_m_approval eq 1}">
    : 승인받은 경우

  • <c:when test="${item.a_m_approval eq 0}">
    : 승인받지 않은 경우.
    : 승인처리 링크를 누르면 /admin/member/setAdminApproval?a_m_no=[해당 계정의 a_m_no] 요청 전송.

 

 


나. 일반 관리자 승인하기

 

“승인처리” 버튼을 누르면 /admin/member/setAdminApproval 요청을 보낸다.

 

1) 컨트롤러

@RequestMapping(value="/setAdminApproval", method = RequestMethod.GET)
public String setAdminApproval(@RequestParam("a_m_no") int a_m_no) {
    System.out.println("[AdminMemberController] setAdminApproval()");

    String nextPage = "redirect:/admin/member/listupAdmin";

    adminMemberService.setAdminApproval(a_m_no);

    return nextPage;
}

AdminMemberController.setAdminApproval 구현.

  • public String setAdminApproval(@RequestParam("a_m_no") int a_m_no) {
    : 쿼리스트링에서 a_m_no 값을 입력받는다.

 


2) 서비스

public void setAdminApproval(int a_m_no) {
    // TODO Auto-generated method stub
    System.out.println("[AdminMemberService] setAdminApproval()");

    int result = adminMemberDao.updateAdminAccount(a_m_no);

}

 


3) DAO

public int updateAdminAccount(int a_m_no) {
    // TODO Auto-generated method stub
    System.out.println("[AdminMemberDao] updateAdminAccount()");

    String sql = "UPDATE tbl_admin_member SET " + "a_m_approval = 1 " + "WHERE a_m_no = ?";

    int result = -1;

    try {
        result = jdbcTemplate.update(sql, a_m_no);
    }catch (Exception e) {
        e.printStackTrace();
    }

    return result;
}
  • String sql = "UPDATE tbl_admin_member SET " + "a_m_approval = 1 " + "WHERE a_m_no = ?";
    : a_m_no로 특정 계정을 찾아서 a_m_approval1로 수정한다.

  • result = jdbcTemplate.update(sql, a_m_no);
    : UPDATE문은 jdbcTemplate.update()을 사용한다.
    : jdbcTemplate.query()와 달리 반환값이 없어 RowMapper는 필요 없다.

승인처리 버튼을 누르면 a_m_approval 값이 1로 변하면서 일반 관리자의 로그인이 승인된다.

 

이후 정상적으로 로그인할 수 있다.

 


'공부 중 > 웹프로그래밍 (Spring)' 카테고리의 다른 글

[Spring] 도서 등록, 검색  (0) 2023.12.31
[Spring] Mail 보내기  (2) 2023.12.21
[Spring] 데이터베이스  (0) 2023.11.09
[Spring] 전자 도서관 서비스 1  (0) 2023.11.08
[Spring] Service, DAO 그리고 VO  (0) 2023.11.07