본문 바로가기

Programming/General

[펌] Cookie에 대한 정리


본 문서는 인터넷 조회를 통해 얻은 내용을 정리한 내용입니다.

 

1. HTTP의 동작방식과 쿠키

 

HTTP 프로토콜의 특성상 클라이언트(브라우저)에서 서버에 데이터를 요청하여 원하는 데이터를 받고 나면, 바로 소켓 Connection을 해제하는 비상태 프로토콜(Stateless Protocol)이다. 즉, 지속적인 연결을 하고 있으면서 데이터를 주고 받는 것이 아니라 필요할 때마다 소켓을 연결하고 데이터를 받자마자 바로 Connection을 끊어버리는 방식이 바로 HTTP 프로토콜의 연결 메커니즘이다.
이는 서버 자원의 낭비를 최소화하는 장점이 되고 있으나, 다음과 같이 페이지를 이동하더라도 지속적인 상태의 유지가 필요한 경우에는 심각한 문제를 유발하지 않을 수가 없게 된다.

 

예를 들어, 전자상거래 사이트에서 로그인후에 물건을 구입하기 위해서 다른 페이지로 이동하면 이전의 상태를 상실하기 때문에 어떤 이름으로 로그인을 했으며, 누가 물건을 구입했는지를 알 수가 없다는 것이다. 고객의 입장에서도 방금전에 구입하기로 하여 장바구니에 넣은 물건이 다른 페이지로 이동하면 자동적으로 상실되는 결과가 초래되기 때문에, 정상적인 전자상거래가 이루어질 수가 없는 것이다.

 

이에 따라 HTTP의 한계를 보완하기 위해 개발된 기술이 쿠키(Cookies)로서, 연결상태의 유지에 필요한 정보를 클라이언트(Client)에 저장하였다가 필요시에 자신이 갖고 있는 정보를 서버(Server)에 보냄으로서 자신이 누군인지 혹은 기타의 상태를 유지하는 개념이다.

 

2. 쿠키의 개념과 동작방식

 

쿠키(Cookies)는 Netscape사에서 정보의 지속성을 위해 고안한 방법으로 HTTP 프로토콜상에서 클라이언트의 상태 정보를 클라이언트의 하드 디스크상에 저장한 후 재사용하는 방식이다. 여기서, 쿠키란 이름 자체는 서버가 클라이언트에 전송하여 저장하는 텍스트 조각(패킷)을 가리키는 것으로, HTTP 헤더에 포함되어 같이 전송된다.

일반적으로 웹 서버가 보통의 HTML 페이지를 보낼 경우 HTTP 헤더는 다음과 같이 설정된다.

    Content-type: text/html

그러나, 웹서버가 HTML 페이지에 쿠키를 설정하고자 할 경우에는 HTTP 헤더에 Set-Cookie 필드가 추가되어 전송된 후 여기서 설정된 쿠키정보가 클라이언트에 저장되는 것이다.

    Content-type: text/html
    Set-Cookie:name=gildong;path=/;expires Mon, 26-Aug-2002  20:13:00 GMT 

여기서 Cookie의 이름은 name이며 이의 값은 gildong으로서 Root 디렉토리 이하에 모두 유효하며 GMT 기준으로 2002년 8월 26일 20:13까지 유효하게 존재하다가 이후 자동으로 삭제된다.

 

3. 쿠키의 사용

3-1. JavaScript 에서의 쿠키 사용

<PRE>function setCookie(name, value, expire) { document.cookie = name + "=" + escape(value) + ( (expire) ? "; expires=" + expire.toGMTString() : "")}</PRE>

여기서 name은 기록할 이름이고 value는 저장할 값이고 expire는 자동삭제 시간입니다. escape(value)는 semicolons, commas, spaces 같은 특수문자를 사용자가 입력했을 경우를 대비해서 해줍니다. 쿠키설정 코드를 짤때 name에도 특수문자를 넣었다면 name도 escape(name)으로 해주어야 합니다. toGMTString()은 cookie에 삭제기간을 지정할 때 사용할 수 있는 함수입니다. 여기에서 domain, path, secure는 지정하지 않았습니다. domain과 path는 지정하지 않으면 현재의 쿠키를 설정하고 있는 domain과 path가 지정되고 secure는 서버의 channel과 연관된 것입니다.

<PRE>function register(uName) { var today = new Date() var expire = new Date(today.getTime() + 60*60*24*31*1000) setCookie("userName", uName, expire)}<form onSubmit="register(this.txt.value)"> 이름이 뭐죠? <input type=text name=txt><input type=submit></form></PRE>

사용자가 이름을 입력하고 submit 하면 31일 후로 자동삭제 기간을 지정하고 userName라는 이름으로 cookie를 설정합니다.

<PRE>function getCookie(uName) { var flag = document.cookie.indexOf(uName+'='); if (flag != -1) { flag += uName.length + 1 end = document.cookie.indexOf(';', flag) if (end == -1) end = document.cookie.length return unescape(document.cookie.substring(flag, end)) }}</PRE>

이 코드로 cookie를 읽습니다. cookie에 저장되는 방식은 저장이름=저장값으로 저장합니다. 저장이름이 다른것이 2개 이상이 저장되어 있다면 저장이름=저장값; 저장이름=저장값 식으로 저장이 됩니다. 등호(=)와 (;)는 자동으로 붙습니다. nn은 브라우저가 있는 폴더에 cookie.txt로 저장하고 ie4는 window가 설치된 곳에 Cookies 폴더에 저장됩니다.

<PRE>function cookieComment() { var userName = getCookie("userName"); if ( userName ) { alert("\n돌아오신 것을 환영합니다.\n\n" + userName + " 님.."); } else alert("\n처음 오셨군요.. 반갑습니다..");}<body onLoad="cookieComment()"></PRE>

Cookie를 읽고 두개 중의 하나의 환영 alert창을 엽니다.

 

Cookie는 사용자가 설정을 선택을 지정할 수 있습니다. 기본값으로는 선택되어 있지만 끌수도 있습니다. 그래서 cookie를 사용하여 특별한 작업을 하기 위해서는 사용자에게 cookie를 선택해 놓으라고 알려 주어야 합니다. cookie를 Client-Side, Server-Side에서 사용하던 마찬가지입니다.

ie4, ie5는 Navigator 객체의 cookieEnabled 라는 요소가 있습니다. 사용 허용은 true 값을 가지고 있고 선택을 꺼놓은 허용 불가는 false 값을 가집니다. 그래서 아래로 cookie를 사용하게 선택해 놓았는지 알 수 있습니다. <PRE>if(navigator.cookieEnabled) { cookie 작업 구문..}else alert("cookie를 꺼놓았습니다. 선택해 주세요..")</PRE>

ie4, ie5에는 cookieEnabled 라는 요소로 알 수 있지만 nn4 이하는 이 요소가 없습니다. 그래서 직접적인 방법을 사용하지 않고 다른 방법을 사용하여야 합니다. 방법은 임시로 아무 cookie 값을 지정하고 그 cookie 값이 있는지 확인하는 방법입니다.

<PRE>document.cookie = 1if(document.cookie) { cookie 작업 구문..}else alert("cookie를 꺼놓았습니다. 선택해 주세요..")</PRE>

cookie에 아무 값이나 지정하고 그 값을 사용하여 그것을 읽으면 굳이 cookie 지정여부를 말해주는 요소가 없어도 nn3 이상의 대부분의 브라우저에서 확인할 수 있습니다

 

* 본 소스는 javascript로 cookie를 가지고 놀자를 참조하였습니다.

<html>
<head>
 <title>Cookie Test</title>
 <script language=javascript type="text/javascript">
  function setCookie ()
  {
   var strValue = getValue();

   var objExpireDate = new Date();

   objExpireDate.setDate(objExpireDate.getDate() + 360);
   
   document.cookie = strValue + "=" + escape(strValue) + "; path=/; expires=" + objExpireDate.toGMTString() + ";";

   initTextBox();
  }

  function delCookie ()
  {
   var strValue = getValue();

   var objExpireDate = new Date();

   objExpireDate.setDate(objExpireDate.getDate() - 1);
   
   document.cookie = strValue + "=;expires=" + objExpireDate.toGMTString();

   initTextBox();
  }

  function getCookieValue (strName)
  {
   var strCookieName = strName + "=";
   var objCookie = document.cookie;
   
   if (objCookie.length > 0)
   {
    var nBegin = objCookie.indexOf(strCookieName);
    
    if (nBegin < 0)
    {
     return;
    }

    nBegin += strCookieName.length;
    
    var nEnd = objCookie.indexOf(";", nBegin);
    
    if (nEnd == -1)
    {
     nEnd = objCookie.length;
    }
   }
   
   return unescape(objCookie.substring(nBegin, nEnd));
  }

  function getAll ()
  {
   var alCookie = document.cookie.split(";")

   var alResult = new Array();
   
   for (i=0; i < alCookie.length; i++)
   {
    if (null == alCookie[i] || "" == alCookie[i])
    {
     continue;
    }

    cookieName = alCookie[i].split("=")[0];
    
    alResult.push(getCookieValue(cookieName));
   }
   
   return alResult;
  }

  function print ()
  {
   var alCookie = getAll();

   alert(alCookie.join());
  }

  function getValue ()
  {
   return document.getElementById("value").value;
  }

  function initTextBox ()
  {
   document.getElementById("value").value = "";
  }
 </script>
</head>
<body bgcolor=white>
 <input type="text" id="value"></input><br />
 <button onclick="setCookie()">set</button>
 <button onclick="delCookie()">del</button>
 <button onclick="print()">print</button>
</body>
</html>

 

4. 쿠키의 제한

* 전체적으로 300개의 쿠키가 저장될 수 있습니다.

* 각 쿠키별로 이름과 값을 합해서 4kb까지 저장될 수 있습니다.

* 서버나 도메인별로 20개의 쿠키가 저장될 수 있습니다.

 

5. 주의 사항

프락시 서버(proxy server)를 이용할 경우 쿠키가 캐쉬되므로 캐쉬되지 않도록 HTTP의 Pragma General Header을 no-cache로 해야 합니다.

 

6. Cookie의 취약점

Cookie Sniffing은 WWW 환경에서 해커가 사용자나 관리자의 Cookie 혹은 Session과 같이 중요한 정보를 가로채는 기법을 말하고 Cookie Spoofing은 이 정보를 이용하여 해커가 자신의 신분을 속이는 행위를 하는 것을 말합니다.

참조 : http://beist.org/research/public/autocookie/index.html Cookie Sniffing 에 사용될 수 있는 자동 공격 프로그램

 

참조 : http://www.cyberu.co.kr/docs/jsp/docs/cookies.asp JSP 프로그래밍 - 쿠키

           http://user.chollian.net/~spacekan/source/cookie/cookie.htm COOKIE

           http://blog.naver.com/kcharon/120049210223 javascript로 cookie를 가지고 놀자