Java

[ Java ] 자바에서 구현 해볼 수 있는 로그인 기법-1 ( 세션 기반 로그인 )

YBin's 2024. 9. 26. 01:27

이번 포스팅에서는 자바에서 써먹을 수 있는 로그인 방법을 끄적여 볼까 한다.

1. Session-based Authentication

세션 기반 로그인은 웹 애플리케이션에서 사용자의 인증 상태를 서버에 저장하고, 그 상태를 유지하는 방식이다.

다시 말해, 사용자가 로그인이 성공하면, 서버는 해당 사용자를 식별하기 위한 세션을 생성하고, 이를 사용자에게 제공한다

 

이후에 사용자가 서버에게 요청을 할 때마다, 제공 받은 세션을 이용하여 인증을 받을 수 있다.

 

 

흐름을 정리하자면 다음과 같다.

 

[ 세션 기반 로그인 흐름 ]
1단계
  로그인 요청
    클라이언트가 사용자 이름과 비밀번호를 서버에 전송
2단계
  인증 처리
    서버가 해당 정보로 데이터베이스를 조회해 유효한 사용자인지 확인
3단계
  세션 생성
    인증에 성공하면 서버는 세션을 생성하고, 세션 ID를 클라이언트에 쿠키로 전송
4단계
  세션 저장
    서버는 해당 세션 ID를 이용해 사용자의 상태나 정보를 서버 메모리 또는 다른 스토리지에 저장
5단계
  세션 확인
    클라이언트가 서버에 요청을 보낼 때마다, 쿠키에 포함된 세션 ID를 사용하여 서버는 해당 사용자가 인증된            상태인지 확인
6단계
  로그아웃
     사용자가 로그아웃하면 세션이 삭제되고, 더 이상 클라이언트가 서버에 요청할 때 인증되지 않음

 

Session 기능을 기본적으로 제공하기 때문에, 우리는 단순히 타닥타닥으로 만들어서 사용하면 된다. 서블릿 기반으로 간단하게 코드를 작성해보겠다.

 

로그인 구현 

- 단순 하드코딩으로 작성해보았는데, 실제로는 DB에서 긁어와서 처리해야 올바르다.

@WebServlet("/udangtang/login")
public class LoginServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        // 데이터베이스에서 사용자 인증 (여기서는 간단히 하드코딩으로 확인)
        if ("admin".equals(username) && "password".equals(password)) {
            // 인증 성공 시 세션 생성
            HttpSession session = request.getSession();
            session.setAttribute("user", username);
            
            // 로그인 성공 메시지 전송
            response.getWriter().println("로그인 성공!");
        } else {
            // 인증 실패 시 메시지 전송
            response.getWriter().println("로그인 실패!");
        }
    }
}

 

 

세션 확인 및 사용자 정보 확인

- 세션 생성 후, 사용자가 서버에 요청을 보낼 때 세션 정보를 이용해사용자를 확인한다. 

@WebServlet("/udangtang/dashboard")
public class DashboardServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession(false); // 세션이 없으면 null 반환
         												// true이면, 세션이 없을 때, 새로 생성한다.
        if (session != null && session.getAttribute("user") != null) {
            String user = (String) session.getAttribute("user");
            response.getWriter().println("환영합니다, " + user + "!");
        } else {
            // 세션이 없으면 로그인 페이지로 리다이렉트
            response.sendRedirect("login.html");
        }
    }
}

 

로그아웃

- 세션이 있다면, 삭제처리 하면 된다.

@WebServlet("/udangtang/logout")
public class LogoutServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession(false); // 세션이 있으면 가져오고, 없으면 null
        if (session != null) {
            session.invalidate(); // 세션 무효화
        }
        response.getWriter().println("로그아웃되었습니다.");
    }
}

 

세션 저장소의 선택

1. 서버 메모리 : 기본적으로 세션은 서버의 메모리에 저장된다. 서버를 재가동 하면, 세션이 초기화 된다.

2. DB 저장 : 세션을 영속적으로 관리하기 위해, 데이터베이스나 Redis와 같은 것을 이용한다.

 + Redis는 인메모리 데이터베이스로 고속 처리가 가능한 녀석인데, 후에 포스팅 될 JWT 로그인 기법에서 좀 더 다루도록 하겠다.

 

세션 타임아웃 관리

세션의 타임아웃을 관리할 때에는 " web.xml " 을 통하여 기본 타임아웃을 설정할 수 있고, setMaxInactiveInterval() 메소드를 통하여 각 세션마다 타임아웃을 지정할 수 있다.

 

두 개의 타임아웃이 모두 사용되었다면,  setMaxInactiveInterval으로 지정된 타임아웃이 우선시 된다.

HttpSession session = request.getSession();
session.setMaxInactiveInterval(3600); // 단위가 "초" 이다. 

-----------

// web.xml에서 세션 타임아웃 설정. 기본 값은 30분이다.
<session-config>
    <session-timeout>20</session-timeout> <!-- 20분 동안 세션 유지, 단위가 "분" 이다. -->
</session-config>

 

장단점

장점

  1. 간단하다. 자바 서블릿 API 기준으로는 기본적으로 세션 관리 기능을 제공하므로, 복잡한 설정이 필요하지 않다.
  2. 상태 관리가 가능하다. 서버가 세션을 직접 관리하므로, 쉽게 참조할 수 있다.

단점

  1. 확장성과 부하 문제가 있다. 세션을 서버 메모리에 저장하면, 서버가 늘어날수록 세션 관리에 어려움이 생긴다. 물론, Redis 같은 외부 세션 저장소를 사용하거나, 세션을 클러스터 간에 동기화하면 어느정도 해결이 가능하다.

 

 

당연하게도 Session 관리하는 방법이나 메소드 등은 아직 매우 많다. 하지만 본 포스팅의 목적은 로그인 기법 소개이므로 추후에 다루어 보도록 하겠다. (언젠가..)

 

다음 포스팅에서는 Spring Security 기반 로그인을 다루어 보도록 하겠다...!