본문 바로가기

네트워크보안/asp

세션(Session)과 쿠키(Cookie) 혼합해서 쓰기.

세션과 쿠키는 클라이언트와 서버간의 연결을 유지하기 위해 사용된다는 공통점이 있습니다만, 위에서 살펴본 것과 같이 저장되는 시점, 만료시점, 리소스 등의 관점에서 보면 뚜렷이 구별되는 몇 가지 차이점을 보이고 있습니다. 그 중 제일 큰 차이점은 저장되는 위치 그리고 그에 따른 정보의 보안문제라고 할 수 있겠죠. 이런 차이에 따라 세션과 쿠키는 웹 프로그래밍에 있어서 나름대로의 독특한 영역을 구축하고 있습니다. 또한 나름대로의 장점들을 살려 혼합해 사용되기도 합니다.

다음은 전자상거래의 간단한 장바구니를 세션과 쿠키를 혼합하여 만든 예입니다. 과일판매 사이트가 있고 그 과일가게에서 사용자가 과일을 골라서 장바구니에 넣는 것입니다. 장바구니의 정보가 하루동안 유지되도록 쿠키로 설정해서 저장해주고, 로그인 할 때 쿠키의 과일 장바구니 목록을 그대로 세션으로 저장해서 사용 함으로서 쿠키와 세션을 혼합하여 사용 하였습니다.

여기서 전제가 되어야 할 사항은 클라이언트는 반드시 쿠키를 사용한다는 것이고, 클라이언트의 컴퓨터는 한 사람만 사용한다는 것입니다. 여기서는 패스워드를 이용한 사용자 로그인 처리를 하지 않아서 여러 개의 ID 설정의 의미가 없기 때문입니다.

grocery.jsp

로그인 인터페이스

<%@ page contentType="text/html; charset=euc-kr" %>

<%
if(session.getAttribute("ID") == null){
%>

<html>
<body>
<h2>Jabook grocery</h2>
<hr>
<form action =
"grocery2.jsp" method = "post">
아이디 : <input type =
"text" name = "id">
<input type =
"submit" value = "승인">
</form>
</body>
</html>

<%
}
else{
response.sendRedirect(
"grocery2.jsp");
}
%>

결과에서 보듯, 아이디를 입력하고 다음 페이지로 넘어가는 인터페이스입니다. 위에서 말씀드렸듯이 패스워드 인증 과정은 생략했습니다.

다음 부분은 사용자 아이디를 받은 후에, 세션의 존재여부를 체크해서 사용자 세션을 만들어 준 다음 클라이언트의 쿠키로부터 목록을 불러와 세션으로 다시 넣어주는 부분입니다.

grocery2.jsp

쿠키를 세션으로 담아 처리하는 페이지

<%@ page contentType="text/html; charset=euc-kr" %>
<%
if(session.getAttribute("ID") == null){
session.setAttribute(
"ID", request.getParameter("id"));
}
String id = (String)session.getAttribute(
"ID");
Cookie cookie[] = request.getCookies();
if (cookie != null cookie.length>1){
for (int i = 0; i<cookie.length-1; i++){
if (cookie[i].getName().equals("apple"))
session.setAttribute(
"apple",cookie[i].getValue());
if (cookie[i].getName().equals("orange"))
session.setAttribute(
"orange",cookie[i].getValue());
if (cookie[i].getName().equals("banana"))
session.setAttribute(
"banana",cookie[i].getValue());
if (cookie[i].getName().equals("cucumber"))
session.setAttribute(
"cucumber",cookie[i].getValue());
}
}
else {
Cookie appleCookie =
new Cookie("apple","0");
Cookie orangeCookie =
new Cookie("orange","0");
Cookie bananaCookie =
new Cookie("banana","0");
Cookie cucumberCookie =
new Cookie("cucumber","0");
session.setAttribute(
"apple", "0");
session.setAttribute(
"orange","0");
session.setAttribute(
"banana","0");
session.setAttribute(
"cucumber","0");
appleCookie.setMaxAge(
1*60*60*24);
orangeCookie.setMaxAge(
1*60*60*24);
bananaCookie.setMaxAge(
1*60*60*24);
cucumberCookie.setMaxAge(
1*60*60*24);

response.addCookie(appleCookie);
response.addCookie(orangeCookie);
response.addCookie(bananaCookie);
response.addCookie(cucumberCookie);
}
%>
<html><body>
<h2>Jabook grocery</h2>
<font color=
"blue"><%=id%></font>님의 방문을 환영합니다. 즐거운 쇼핑 되세요
<hr>
<b>현재 장바구니에 담긴 품목</b>
<font size =
"2">(새로 담으신 품목은 하루동안 그 정보가 유지됩니다)</font><br>
*사과 : <%=session.getAttribute(
"apple")%> 개<br>
*오렌지 : <%=session.getAttribute(
"orange")%> 개<br>
*바나나 : <%=session.getAttribute(
"banana")%> 개<br>
*오이 : <%=session.getAttribute(
"cucumber")%> 개<br>
<a href =
"grocery4.jsp"><font size = "2">[모두 구매 및 배달]</font></a>
<hr>
한번에 한개씩..
<form action =
"grocery3.jsp" method = "post">
<input type =
"checkbox" name = "apple">사과
<input type =
"checkbox" name = "orange">오렌지
<input type =
"checkbox" name = "banana">바나나
<input type =
"checkbox" name = "cucumber">오이<br><br>
<input type =
"submit" value = "장바구니에 담기">
</form>
</body></html>

먼저 세션의 ID항목을 체크해서 존재하지않으면, 앞에서 받아온 사용자 아이디를 값으로 새로운 세션 ID를 생성합니다.

n if(session.getAttribute("ID") == null){

n session.setAttribute("ID", request.getParameter("id"));

n }

클라이언트에 설정한 쿠키를 모두 불러와서 원하는 정보(과일 정보)의 쿠키값을 추출하여 그 값을 그대로 세션에 설정합니다.

n Cookie cookie[] = request.getCookies();

n if (cookie.length>1){

n for (int i = 0; i<cookie.length-1; i++){

n if (cookie[i].getName().equals("apple"))

n session.setAttribute("apple",cookie[i].getValue());

만약 쿠키가 설정되어 있지 않을 경우, 새로운 장바구니 목록으로 쿠키를 설정하여 줍니다. 여기에는 과일의 이름과 함께 현재 장바구니에 선택한 과일의 수를 초기화(0)해 놓았습니다.

n Cookie appleCookie = new Cookie("apple","0");

n Cookie orangeCookie = new Cookie("orange","0");

n Cookie bananaCookie = new Cookie("banana","0");

n Cookie cucumberCookie = new Cookie("cucumber","0");

역시 초기정보를 세션으로 저장하고 쿠키의 유효시간을 24시간으로 설정한 후 응답으로 쿠키를 클라이언트에 저장합니다.

n session.setAttribute("apple", "0");

n appleCookie.setMaxAge(1*60*60*24);

n response.addCookie(appleCookie);

다음은 브라우저에 출력을 하는 부분으로, 세션에 담긴 장바구니 목록을 받아와서 출력하여 줍니다.

n *사과 : <%=session.getAttribute("apple")%> 개<br>

n *오렌지 : <%=session.getAttribute("orange")%> 개<br>

n *바나나 : <%=session.getAttribute("banana")%> 개<br>

n *오이 : <%=session.getAttribute("cucumber")%> 개<br>

[모두 구매 및 배달]에 링크가 걸려서 grocery4.jsp로 보내주고 있습니다. grocery4.jsp에서는 실제로 결재처리 및 배달에 관한 것은 구현되어 있지않고 단지 쿠키를 초기화 하는 일만 합니다.

n <a href = "grocery4.jsp"><font size = "2">[모두 구매 및 배달]</font></a>

그리고 다음은 장바구니에 과일을 더하기 위한 선택목록을 HTML 폼으로 작성한 것입니다. 목록에 체크를 한 후 그 결과를 폼의 Post 방식으로 보내면, grocery3.jsp 파일에서 처리해 줍니다.

grocery3.jsp에서는 세션에서 장바구니 목록을 얻은 후 폼으로 넘어온 선택 정보를 더해서 그 결과를 다시 쿠키로 설정합니다. 그리고 앞의 페이지로 response.sendRedirect 메서드를 통해 보냄으로서 장바구니 목록을 갱신하여 클라이언트에게 보여줍니다.

grocery3.jsp

사용자 선택정보를 처리하는 페이지

<%@ page contentType="text/html; charset=euc-kr" %>

<%
int apple = Integer.parseInt((String)session.getAttribute("apple"));
int orange = Integer.parseInt((String)session.getAttribute("orange"));
int banana = Integer.parseInt((String)session.getAttribute("banana"));
int cucumber = Integer.parseInt((String)session.getAttribute("cucumber"));

String app = request.getParameter(
"apple");
String org = request.getParameter(
"orange");
String ban = request.getParameter(
"banana");
String cuc = request.getParameter(
"cucumber");

if (app != null && app.equals("on")){
Cookie appleCook =
new Cookie("apple", apple+1+"");
appleCook.setMaxAge(
1*60*60*24);
response.addCookie(appleCook);
}

if (org != null && org.equals("on")){
Cookie orangeCook =
new Cookie("orange", orange+1+"");
orangeCook.setMaxAge(
1*60*60*24);
response.addCookie(orangeCook);
}

if (ban != null && ban.equals("on")){
Cookie bananaCook =
new Cookie("banana", banana+1+"");
bananaCook.setMaxAge(
1*60*60*24);
response.addCookie(bananaCook);
}

if (cuc != null && cuc.equals("on")){
Cookie cucuCook =
new Cookie("cucumber", cucumber+1+"");
cucuCook.setMaxAge(
1*60*60*24);
response.addCookie(cucuCook);
}

response.sendRedirect(
"grocery2.jsp");
%>

우선 결과를 보시면, 목록에서 사과와 오렌지에 체크후 장바구니에 담기 버튼을 누르면 그 결과가 반영되어서 사과와 오렌지의 갯수가 하니씩 늘어나 있는 것을 확인할 수 있을 것입니다. 소스 분석을 통해 그 과정을 살펴보죠.

세션으로부터 해당 과일 이름의 값(value)을 읽어옵니다. 그런데 위에서 세션에 집어넣을때는 String 형의 값이 Object 형으로 업캐스팅 되어서 들어갔으므로 여기서는 반대로 String 형으로 다운캐스팅 후, 다시 계산을 위해서 int 형으로 바꾸어주고 있습니다.

n int apple = Integer.parseInt((String)session.getAttribute("apple"));

폼으로 넘어온 값을 받고 있습니다. 체크박스로 넘어왔기 때문에 체크가 되어있던 것은 on의 값을 가지고 있고, 체크되지 않았던 것은 null 값을 가지고 있습니다.

n String app = request.getParameter("apple");

받은 값을 검사하여 그 값이 null이 아니며 on이라면 세션으로부터 얻은 과일의 정보 즉, 선택한 과일의 갯수에 하나를 더해서 다시 쿠키로 설정하고 grocery2.jsp로 보냅니다.

n if (app != null && app.equals("on")){

n Cookie appleCook = new Cookie("apple", apple+1+"");

n appleCook.setMaxAge(1*60*60*24);

n response.addCookie(appleCook);

n }

n response.sendRedirect("grocery2.jsp");

앞의 쿠키 설정의 생성자 부분을 보시면 new Cookie(apple, apple+1+ “” )라고 되어있습니다. 쿠키는 생성자로 이름과 값으로 된 한 쌍의 String형 value를 받기 때문에 위와 같은 방식으로 숫자를 String형으로 바꾸어 주었습니다. 이런 것도 하나의 노하우라고 할 수 있겠죠.

다음으로 grocery4.jsp 페이지에서는 [모두 구매 및 배달] 링크를 눌렀을 때 장바구니의 모든 목록을 0으로 해주는 일을 합니다. 즉, 쿠키의 값을 초기화시켜 다시 grocery2.jsp 페이지로 보냅니다.

grocery4.jsp

사용자 선택정보를 처리하는 페이지

<%@ page contentType="text/html; charset=euc-kr" %>
<%
//---결재, 배달 메커니즘 구현했다고 가정 ---

Cookie appleCookie = new Cookie("apple","0");
Cookie orangeCookie =
new Cookie("orange","0");
Cookie bananaCookie =
new Cookie("banana","0");
Cookie cucumberCookie =
new Cookie("cucumber","0");
appleCookie.setMaxAge(
1*60*60*24);
orangeCookie.setMaxAge(
1*60*60*24);
bananaCookie.setMaxAge(
1*60*60*24);
cucumberCookie.setMaxAge(
1*60*60*24);
response.addCookie(appleCookie);
response.addCookie(orangeCookie);
response.addCookie(bananaCookie);
response.addCookie(cucumberCookie);
response.sendRedirect(
"grocery2.jsp");
%>

결과를 보시면 왼쪽 그림에서 [모두 구매 및 배달]을 누르면 사과4개, 오렌지5개, 바나나2개, 오이1개의 항목이 모두 초기화되어 오른쪽 그림과 같이 모두 0개로 나타납니다.

이것은 아래와 같이 쿠키를 생성하여 각 이름의 값을 0으로 설정하여 주었기 때문입니다. 쿠키는 같은 이름으로 저장하면 먼저 있던 것이 삭제된 후 새로운 쿠키가 설정되기 때문입니다.

n Cookie appleCookie = new Cookie("apple","0");

n appleCookie.setMaxAge(1*60*60*24);

n response.addCookie(appleCookie);

그리고 이 페이지도 역시 grocery2.jsp 페이지로 Redirect해서 결과를 보여주고 있습니다.

n response.sendRedirect("grocery2.jsp");

이와 같이 간단한 예제를 통해서 세션과 쿠키의 혼합 사용을 다루어 보았습니다. 하지만 앞서도 언급하였지만, 사용자가 보안이나 개인정보 유출을 우려해서 쿠키사용을 하지 않는다면, 위의 예제는 의미가 없는 것입니다. 그럴 때는 쿠키 대신에 서버의 데이터베이스를 설정하여 사용자의 장바구니 목록을 저장해 둘 수도 있을 것입니다.


'네트워크보안 > asp' 카테고리의 다른 글

URL에 자동으로 세션(Session) ID 달고 다니기  (0) 2012.02.15
세션(session) 종료하기  (0) 2012.02.15
세션(Session) 값 얻기  (0) 2012.02.15
세션(Session) 값 설정  (0) 2012.02.15
세션(Session)이란?  (0) 2012.02.15