▸JSP & Servlet/기본 문법

JSP 내장 객체_session (쿠키와 세션) [4/4]

코데방 2020. 2. 17.
728x90

[ JSP 내장 객체 ]

  • 개발자가 객체를 별도로 생성하지 않아도 JSP에서 바로 사용할 수 있는 객체
  • 컨테이너가 JSP를 서블릿으로 변환할 때 자동으로 객체가 생성됨
  • request, response, out, page, config, application, pageContext, exception, session

내장 객체는 말 그대로 JSP가 기본적으로 내장하고 있어서 따로 선언하거나 만들어줄 필요 없이 바로 사용 가능한 객체를 말합니다. 당연한 말이지만 모두 Java의 클래스 객체이므로 서블릿에서도 동일하게 사용이 가능합니다. 서블릿에서는 자동으로 생성되는 내장 객체는 아니지만 대부분 get 메소드를 이용해 객체를 얻어낼 수 있습니다. 

 

전반적인 구조에 대한 아래 링크글을 먼저 참조하시면 좀 더 이해가 수월할 수 있습니다.

 

JSP 내장객체의 구조와 생명주기 (session / config / application )

 

 


 

 

[ session - javax.servlet.http.HttpSession 객체 ]

 

session 객체는 클라이언트와 서버와의 관계를 유지해주는 수단입니다. 그냥 세션(Session)이라는 용어는 '연결된 상태'라는 의미입니다. 채팅 프로그램을 만들 때처럼 일반적으로 자바를 이용해 클라이언트-서버 간 프로그램을 작성할 때는 소켓을 이용해 통신을 연결합니다. 이 경우 서버의 서버소켓과 클라이언트의 소켓이 연결된 상태를 세션이 맺어졌다고 표현합니다. 그리고 클라이언트 또는 서버에서 해당 연결을 끊지 않는 한 세션이 계속 맺어진 상태로 있으며 세션이 끊길 경우 통신이 종료되고 다시 연결하기 위해서는 프로그램을 재구동 해서 다시 세션을 맺어줘야 합니다.

 

하지만 HTTP 프로토콜은 계속 세션을 맺은 상태로 클라이언트와 서버가 연결돼 있는 것이 아니라 클라이언트가 서버에 요청을 할 때 세션이 맺어지고 서버에서 클라이언트로 응답을 보낸 이후 세션이 끊깁니다. 서버 입장에서는 요청에 따른 응답을 하고 나면 클라이언트와의 연결이 끊어지므로 더 이상 클라이언트에 대해 신경쓰지 않게 됩니다.

 

하지만 이렇게 세션이 매번 끊어져버린다면, 예를 들어 웹 사이트에서 클라이언트가 로그인을 요청하고 서버가 해당 계정을 확인한 뒤 로그인이 완료된 다음 페이지를 보여주더라도 계속해서 클라이언트가 로그인된 상태를 유지하기 어렵게 됩니다. 따라서 세션이 끊어지더라도 지속적으로 서버측에서 클라이언트에 대한 접속 정보를 가지고 있음으로써 로그인을 유지할 수 있게 해주는 객체가 바로 JSP의 내장객체이자 자바의 HttpSession 객체인 session 입니다. 로그인 뿐만 아니라 지속적인 관계를 유지해야하는 서비스에서 session 객체를 활용할 수 있습니다. 

 

 

* 쿠키(Cookie)와 세션(Session)의 차이점

 

쿠키는 서버가 보내준 특정한 정보를 클라이언트(브라우저) 측에서 가지고 있는 방식입니다. 로그인의 예를 들면 로그인을 통과했을 경우에만 특정 정보값과 계정정보를 클라이언트측에 저장하게 하고 로그인 된 이후의 페이지에 대한 요청이 올 때는 클라이언트의 쿠키 정보에 로그인을 통과한 정보가 있는지를 판단하고 계정정보를 가져와 해당 계정에 관한 정보를 출력해주는 방식으로 사용할 수 있습니다. 하지만 클라이언트측에서 인증 정보를 가지고 있는 경우는 보안이 취약하다는 단점이 있습니다. 해당 정보를 조작해서 서버의 인증을 우회하는 방식 등이 사용됩니다. 

 

하지만 세션의 경우는 서버에서 클라이언트에 대한 정보를 가지고 있다는 점에서 쿠키와 다릅니다. 서버에서 정보를 관리함으로써 쿠키에 비해 보안을 향상시킨 방법입니다. 따라서 로그인 인증과 같은 민감한 정보에 대해서는 쿠키보다 세션 방식을 사용하는 것이 좋습니다. 또한 쿠키는 저장할 수 있는 데이터의 한계가 있는 반면 세션은 서버에 저장되는 정보이기 때문에 저장할 수 있는 데이터의 한계가 없다는 장점도 있습니다.

 

쿠키 관련해서는 아래 링크글을 참조하시면 됩니다.

 

2020/02/18 - [· JSP & Servlet/- 기본 문법] - 쿠키(Cookie)

 

 


 

 

세션 객체는 컨테이너에서 자동으로 생성해줍니다. 세션의 단위는 브라우저입니다. 같은 PC에서도 다른 브라우저로 접속하면 다른 사용자로 인식합니다. 크롬에서 로그인하고 익스플로러도 다시 켜보면 로그인이 안돼있는 것이 이 때문입니다. 또 브라우저가 완전히 다 닫히고 다시 열리게 되도 식별자가 달라서 다른 세션으로 인식합니다. 하지만 브라우저가 완전히 닫히지 않은 상태에서 창을 하나 더 열 때는 같은 브라우저로 인식합니다 .예를 들어 크롬창을 두 개 열어서 한쪽에서 로그인을 하고 다시 껐다 키더라도 다른 하나의 창을 끄지 않았기 때문에 같은 브라우저로 인식해 session 객체를 새로 생성하지 않습니다. 같은 브라우저를 여러 개 키고 하나의 브라우저로 로그인을 했을 때 다른 브라우저에서도 로그인이 돼 있는 것은 이 때문입니다.

 

세션 정보는 계속 유지해줄 수도 있지만 대부분 권고되는 보안 규정에 따라 30~60분 사이로 세션이 유지되는 최대 시간을 조절해 주는 경우가 많습니다. 디폴트는 대부분 30분으로 web.xml에 <session-timeout> 태그에 기술되어 있습니다. 이 부분에서 시간을 조정해주거나 메소드를 통해 재조정해줄 수도 있습니다. 

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

 

 

session 주요 메소드 설명
void setAttribute(String name, Object value) 파라미터 이름에 따른 객체를 추가
Object getAttribute(String name) 파라미터 이름에 따른 객체를 반환
void removeAttribute(String name) 파라미터 이름에 따른 객체를 삭제
void invalidate() 세션의 모든 삭제를 삭제 (세션 무효화)
Enumeration<String> getAttributeNames() 등록된 모든 파라미터 이름을 반환
String getID() 해당 세션(브라우저)의 고유 식별자 정보 반환
Boolean isNew() 세션 객체가 최초로 생성되었는지 여부 반환
void setMaxInactiveInterval(int interval) 세션이 유지되는 유효시간을 설정
int getMaxInactiveInterval() 세션에 설정된 유효시간을 반환

 

 

컨테이너는 브라우저에서 요청이 들어오면 session 객체를 생성해준다고 했습니다. 이 때 브라우저의 고유 식별자(ID)를 받아서 같은 식별자를 가진 session 객체가 있으면 해당 객체를 가져다 쓰고, 없으면 새로 만들어줍니다. 그리고 session 객체를 계속 보관하고 있다가 유효시간이 지나면 무효화를 시키고 무효화가 되기 전이라면 기존 session 객체가 남아있으므로 이미 인증이 된 클라이언트가 맞는지 구분할 수 있게 됩니다. 

 

새로 생성된 객체는 isNew() 메소드에서 'true'를 반환하지만, 만약 한번이라도 다른 JSP 페이지나 서블릿을 거쳐서 왔다면 이미 세션이 생성된 상태가 되어 'false'를 반환하게 되므로 사용 시 주의해야합니다. 

 

 

 


 

 

아래는 세션을 사용한 로그인 로직을 확인해보기 위해 대충 짜본 코드입니다. 처음 로그인 페이지에 접속했을 때부터 세션에 등록된 userId 값이 있는지 확인하고 없으면 로그인을 진행하고 있으면 로그인이 이미 된 것으로 간주해 메인페이지로 리다이렉트해주는 간단한 코드입니다. 로그아웃 버튼을 눌러 invalid() 메소드를 호출하기 전이나 세션 타임아웃 전까지는 다시 로그인 페이지에 접속해도 바로 메인 페이지로 이동됩니다. 원리만 이해하면 필요에 맞게 사용하면 됩니다. 

 

첫 로그인

 

메인페이지 (다시 로그인 페이지로 들어가도 메인페이지로 리다이렉트)

 

로그아웃 버튼 누르면 다시 로그인창으로 이동

 

* login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

	<%
		if (session.getAttribute("userId") != null) {
			response.sendRedirect("main.do");
		}
	%>

	<form action = "join.do" method = "post">
		id : <input type = "text" name = "userId" size = "10"><br/>
		pw : <input type = "text" name = "userPw" size = "10">
		<input type = "submit" value = "전송">
	</form>


</body>
</html>

 

* main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

	<%!
		String id;
	%>
	
	<%
		id = (String)session.getAttribute("userId");
	%>
	
	<br/> <%= id %>님 안녕하세요~ 로그인이 돼있습니다~! <br/>
	
	<form action = "logout.do" method = "post">
		<input type = "submit" value = "로그아웃">
	</form>
	
</body>
</html>

 

* Controller.java (서블릿)

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("*.do")
public class Controller extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public Controller() {
		super();
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doAction(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doAction(request, response);

	}

	public void doAction(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		try {
			request.setCharacterEncoding("UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 요청된 페이지 확인
		String uri = request.getRequestURI();

		// session 확인
		HttpSession session = request.getSession();
		String user = (String) session.getAttribute("userId");

		// login.jsp에서 로그인 정보를 입력했을 때 (인증 생략)
		if (uri.equals("/join.do")) {

			// session에 아이디 추가 하고 메인 페이지로 보냄
			String id = request.getParameter("userId");
			session.setAttribute("userId", id);
			response.sendRedirect("main.jsp");

		// 로그아웃 버튼 눌렀을 때
		} else if (uri.equals("/logout.do")){
			
			// 세션 무효화시키고 로그인 페이지로 이동
			session.invalidate();
			response.sendRedirect("login.jsp");
			
		} else {
		
			// 세션 정보에 저장된 아이디 값이 없으면
			if (user == null) {
				System.out.println(uri);
				// 로그인 페이지로 보냄
				response.sendRedirect("login.jsp");

			// 세션 정보에 저장된 아이디 값이 있으면
			} else {
				// 메인 페이지로 보냄
				response.sendRedirect("main.jsp");
			}
		}
	}
}

 

728x90

댓글

💲 추천 글