세션을 이용한 로그인, 로그아웃 구현하기
이번글에서는 세션을 통한 로그인 및 로그아웃을 간단한 예제로 만들어볼것입니다. 로그인, 로그아웃이라고는 했지만 사실상 세션을 어떤식으로 사용하는지에 대한 간략한 설명이 목적이므로 보안적인 사항등은 제외되어있으니 이 포스팅을 읽는 분들은 양해 부탁드립니다.


로그인 로그아웃 예제
로그인 및 로그아웃은 다음과 같이 세 개의 페이지를 통해 표현할 것입니다. 간략하게 설명하자면 각각의 화면은 다음과 같습니다.


login.html
최초에 사용자가 보게될 화면이며, 로그인을 수행하는 화면입니다. 로그인 버튼을 누르면 로그인 결과 JSP가 호출됩니다.

loginResult.jsp
로그인 결과 JSP에서는 login.html에서 보내온 정보로 로그인을 수행하고 로그아웃 버튼이 있어 로그아웃 할 수 있습니다. 만약 로그인에 실패하거나 로그인 되어있지 않은 상태로 페이지를 요청하면 로그인화면 HTML로 리다이렉트시킵니다. 로그인의 성공여부는 아이디와 패스워드가 같은값이면 성공처리합니다.

logout.jsp
로그인결과 페이지에서 로그아웃 클릭시 호출되는 페이지이며 세션을 종료시켜 로그인되었다는 상태 정보를 지웁니다.



예제 코드
login.html
login.html은 별다른 것은 없고 아이디와 비밀번호를 입력할 수 form을 가지고 있습니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<body>
      <form action="loginResult.jsp" method="post">
            아이디 : <input type="text" name="id"><br>
            비밀번호 : <input type="password" name="password"><br>                            
            <input type="submit" value="로그인">
      </form>
</body>
</html>
cs




logout.jsp
로그아웃 페이지는 가장 심플한데, 세션을 종료시키고 로그아웃 되었음을 알려주는 코드입니다.
<%@ page contentType="text/html; charset=utf-8"%>                                        
 
 
<html>
<head>
</head>
<body>
<%
    HttpSession userSession = request.getSession();
    userSession.invalidate();
    out.println("<h1>로그아웃 되었습니다.</h1>");
%>
</body>
</html>
cs



loginResult.jsp
가장 중요한 로그인 결과 페이지입니다.
로그인 결과를 보여줄 JSP 페이지이며, 여기서는 세션을 다루는것을 보여주는것이 목적이므로 DB와 연동하는 기능은 구현하지 않았습니다. 단순히 입력한 id와 password가 서로 동일한 값이면 로그인으로 처리하는것으로 합니다.

또한 로그인에 성공시 isLogined 라는 세션값을 저장하여 로그인 되었다는 여부를 저장합니다. 만약 입력한 id와 password가 없고 isLogined 값이 false 이거나 없는 경우에는 비정상적인 접근인것으로 보고 login.html로 리다이렉트 시킵니다.
<%@ page contentType="text/html; charset=utf-8"%>                                        
 
 
<%!
      private boolean isEmpty(String str){
          if(str == null || str.trim().equals("")){
             return true
            } 
      
            return false
      }
 
 
       private final String successHtml = "<h1>로그인 상태입니다</h1> \n"  + 
                                         "<a  href=\"logout.jsp\">로그아웃</a>";
                                                   
%>
 
 
<html>
<head>
</head>
<body>
<%
    String id = request.getParameter("id");
    String password = request.getParameter("password");
    Boolean isLogined = (Boolean) session.getAttribute("isLogined");
 
 
    //로그인 상태인지 여부 확인
    if (isLogined != null && isLogined) {
        out.println(successHtml);
    } else {
        //로그인 상태가 아닌 경우
        //id와 비밀번호를 모두 입력했는지 여부 확인
        if (isEmpty(id) || isEmpty(password)) {
            response.sendRedirect("/login.html");
        } else {
            //id와 비밀번호를 모두 입력했고 id와 password가 같다면  로그인처리
            if (id.equals(password)) {
                session.setAttribute("isLogined"true);
                out.println(successHtml);
            } else { 
                //id와 password가 같은값이 아니면 로그인 실패로 간주
                response.sendRedirect("/login.html");
            }
        }
    }
%>
 
 
</body>
</html>
cs

 

 


loginResult.jsp 파헤쳐보기
그럼 코드를 조각조각 살펴보도록 하겠습니다.

아래 '<%!' 로 시작하는 부분은 선언문으로 JSP 페이지가 서블릿으로 변환될 때 서블릿의 멤버로 변경되는 부분입니다. 따라서 isEmpty() 메서드는 변경될 서블릿의 멤버메서드가 되며, 매개변수로 넘겨받은 문자열이 null이거나 비어있는 문자열인지의 여부를 확인하는 메서드입니다.

successHtml은 JSP 페이지가 변경될 서블릿의 멤버변수이며, 로그아웃 링크를 가진 a태그를 HTML 문법에 맞게 작성된 문자열입니다. 멤버변수이므로 현재 JSP 페이지 어디에서든 접근할 수 있습니다.
<%!
      private boolean isEmpty(String str){
          if(str == null || str.trim().equals("")){
             return true;
            }
      
            return false;
      }
 
 
       private final String successHtml = "<h1>로그인 상태입니다</h1> \n"  +
                                         "<a  href=\"logout.jsp\">로그아웃</a>";            
                                                   
%>
cs


다음으로 가장 중요한 부분입니다. 스크립트릿으로 현재 JSP 페이지가 실제로 실행될 코드입니다. 가장 먼저 요청 파라미터 id값과 password 그리고 세션에서 'isLogined' 라는 이름을 가진 attribute를 꺼내오고 있습니다. isLogined는 로그인 되어있는지의 여부를 저장한것입니다. 만약 id나 password가 요청파라미터에 없거나 'isLogined'라는 이름을 가진 attribute가 세션에 저장되어 있지 않다면 null을 리턴할 것입니다.
<%
    String id = request.getParameter("id");
    String password = request.getParameter("password");
    Boolean isLogined = (Boolean) session.getAttribute("isLogined");        
cs


다음으로는 세션에서 꺼낸 isLogined가 true이면 로그인 되었다는 것으로 간주하여 로그인 상태라는 결과와 로그아웃 링크버튼을 출력하는 부분입니다. isLogined이 null일 경우를 대비한 조건문도 넣어주었습니다.
    if (isLogined != null && isLogined) {                                    
        out.println(successHtml);
    }
cs


마지막 부분입니다. 로그인이 되어있지 않은 경우에는 id와 password를 검사합니다. 가장 먼저 id나 password를 사용자가 로그인시 입력했는지 검사합니다. 하나라도 입력하지 않았으면 로그인 페이지로 리다이렉트시킵니다.

모두 입력되었다면 id과 password가 같은값인지 검사하고 같으면 이전과 마찬가지로 로그인 상태라는 결과를 리턴, 값이 서로 다른경우 리다이렉트 처리합니다.
    else {
        //로그인 상태가 아닌 경우
        //id와 비밀번호를 모두 입력했는지 여부 확인
        if (isEmpty(id) || isEmpty(password)) {
            response.sendRedirect("/login.html");
        } else {
            //id와 비밀번호를 모두 입력했고 id와 password가 같다면  로그인처리        
            if (id.equals(password)) {
                session.setAttribute("isLogined"true);
                out.println(successHtml);
            } else { 
                //id와 password가 같은값이 아니면 로그인 실패로 간주
                response.sendRedirect("/login.html");
            }
        }
    }
cs


if else문이 많아 코드가 보기 어렵습니다. 사실 저의 경우는 else문 없이 if문만으로 조건을 주거나 if문을 하나의 depth 안에서 사용하는것을 좋아합니다. 코드가 좀 더 간결해지기 때문입니다.
        if (isEmpty(id) || isEmpty(password)) {
            response.sendRedirect("/login.html");
        }
 
 
           //id와 password가 같은값이 아니면 로그인 실패로 간주                     
        if (!id.equals(password)) {
            response.sendRedirect("/login.html");
        }
 
 
        session.setAttribute("isLogined"true);
        out.println(successHtml);
 
cs



그러나 위와 같은 식으로 처리하지 못한 이유가 있습니다. 리다이렉트를 실행하여도 그 다음 코드들이 실행되기 때문입니다. 이에 대한 자세한 내용은 포스팅 하단의 참고글 링크를 이용해주세요.
response.sendRedirect("/login.html");                                            
...이후 코드가 실행됨...
cs




세션 확인 필터
지금까지 로그인 처리를 구현하였는데, 만약 게시판이나 비밀 게시글, 사용자관리 페이지 등 여러 페이지를 개발하게 된다면 어떨까요? 세션이 존재하는지 여부를 모든 페이지에서 체크해야 합니다. 이런 경우는 세션을 확인하여 로그인이 되어있는 사용자인지의 여부를 필터에서 처리해주는것이 좋습니다. 실제로 실무에서는 필터나 스프링의 인터셉터등을 통해 로그인 여부를 검사합니다. 그러나 이 글에서의 범위를 넘어서는 부분이므로 그렇다 정도로만 알아주시면 될 것 같습니다.




참고글
블로그 이미지

도로락

IT, 프로그래밍, 컴퓨터 활용 정보 등을 위한 블로그

,