게시판
      
상위분류 : 잡필방 중위분류 : 서류가방 하위분류 : 전산과 컴퓨터
작성자 : 문시형 작성일 : 2016-08-24 조회수 : 4,792
제 목 : 쿠키 Cookie 사용법,

MKEX Dev .NET

『 Cookie 제대로 알고 사용하자 』

 

Cookie 는 아주 보편적이고 유명(?)하기 까지 하다.

웹 개발자는 물론이고 일반 웹 유저들 마저 쿠키에 대해 어느 정도는 알고 있다.

비 연결 지향인 웹 환경에서 사용자(일반적으로 웹 브라우저가 되겠다)와 웹 서버간의 특정 데이터의 상태 정보 저장을 위해 사용하는 하나의 기법이다.

 

이번 아티클은 이렇게 보편적인 쿠키를 개발단에서 사용할 때 참고할 만한 내용들을 정리해 본다.

 

1. 쿠키는 어디에 저장되는가?

    일반적으로 쿠키는 아래의 경로에 TXT 파일 형태로 저장이 된다.

 ‘C:\Documents and Settings\현재로그인한 사용자\Cookies

 그러나 서버에서 쿠키의 만료 일자를 지정하지 않았다면 파일로 저장되지 않고 사용자 세션정보의 일부로써 유지

 된다.  즉 브라우저 기반 쿠키로써 브라우저를 닫으면 쿠키 역시 소멸되는 것이다

 쿠키를 파일로 저장하지 않는 것은 보안상 이슈로 더 좋은 선택이 될 수 있다. 
    결론적으로, 쿠키를 설정할 때 만료일자의 지정 유/무에 따라 파일기반 쿠키 또는 세션(브라우저)기반 쿠키로 저장

 되는 것이다

 

 참고> 만일 파일기반 쿠키의 경우 동일한 이름의 쿠키를 저장할 경우 이전 쿠키파일을 덮어 쓰게 된다

 

2. 쿠키의 제한 사항

   웹 서버가 클라이언트에게 쿠키를 저장 할 경우 대부분 아래와 같은 제약 사항을 가진다.

   1) 하나의 사이트에서 클라이언트에게 저장할 수 있는 최대 쿠키는 20개까지 이다.       

   2) 최대 4096 byte 쿠키 지원

 

    쿠키의 수적 제한과 최대 크기의 제한 사항은 하위키 형태의 쿠키로 해결 할 수 있다.

    즉, 만일 한 사이트에서 20개 이상의 쿠키가 필요하다면 하위 키를 포함한 쿠키를 사용하면 더 많은 쿠키를 저장

    하는 효과를 볼 수 있다.

    Cookie[“Key”][“하위키1”]; Cookie[“Key”][“하위키2”];

    이에 대한 MSDN 내용은 다음과 같다.

   

하위 키를 포함하는 쿠키를 사용하면 쿠키 파일의 크기를 제한하는 데에도 도움이 됩니다.

일반적으로 쿠키는 4096바이트로 제한되고 각 사이트마다 최대 20개의 쿠키를 저장할 수 있습니다.

하위 키를 포함하는 단일 쿠키를 사용하면 사이트에 할당된 20개의 쿠키보다 적은 수의 쿠키를 사용하게 됩니다.

또한 단일 쿠키에는 오버헤드(만료 정보 등)에 대한 50개 정도의 문자와 쿠키에 저장되는 값의 길이가 포함됩니다.

이 값은 모두 4096바이트 제한에 거의 근접한 값입니다. 5개의 쿠키를 개별적으로 저장하는 대신 하위 키 5개를 저장하면 개별 쿠키로 인한 오버헤드를 줄여 약 200바이트를 절약할 수 있습니다.

 

 

3. 쿠키 샘플

   이제 ASP.NET 에서 쿠키를 저장하고 불러오는 샘플 코드를 보자.

 
  1. 쿠키 저장하기
    아래 샘플 코드는 하위키를 가진 쿠키를 저장하는 두 가지 방법을 나타낸다

Response.Cookies["MyCookie"]["Cookie1"] = "값1";

Response.Cookies["MyCookie "][" Cookie2"] = “값2”;

Response.Cookies["MyCookie "].Expires = DateTime.Now.AddDays(1);

 

HttpCookie aCookie = new HttpCookie("MyCookie ");

aCookie.Values["Cookie1"] = " 값1";

aCookie.Values["Cookie2"] = “값2”

aCookie.Expires = DateTime.Now.AddDays(1);

Response.Cookies.Add(aCookie);

 

  1. 쿠키 불러오기

아래 샘플 코드는 하위키를 가진 쿠키를 불러오는 방법을 나타낸다

샘플 처럼 해당 쿠키가 존재하는지 여부를 체크 하는 것이 좋다.

(그렇지 않으면 ‘NullReferenceException’ 이 발생할 수 있다)

 

if(Request.Cookies["MyCookie "] != null)

{

    Label1.Text =

        Server.HtmlEncode(Request.Cookies["MyCookie "][" Cookie1"]);

 

    Label2.Text =

        Server.HtmlEncode(Request.Cookies["MyCookie "][" Cookie2"]);

}

 

 

    MSDN : 쿠키 값을 표시하기 전에 HtmlEncode 메서드를 호출하여 쿠키 내용을 인코딩했습니다.

                이렇게 하면 악의적인 사용자가 실행 스크립트를 쿠키에 추가할 수 없습니다.

 

  1. 모든 쿠키 읽기

현재 나의 사이트에서 저장한 모든 쿠키를 알아 볼 수 있는 샘플 코드이다. (MSDN)

for(int i=0; i<Request.Cookies.Count; i++)

{

    aCookie = Request.Cookies[i];

    output.Append("Name = " + aCookie.Name + "<br />");

    if(aCookie.HasKeys)

    {

        for(int j=0; j<aCookie.Values.Count; j++)

        {

            subkeyName = Server.HtmlEncode(aCookie.Values.AllKeys[j]);

            subkeyValue = Server.HtmlEncode(aCookie.Values[j]);

            output.Append("Subkey name = " + subkeyName + "<br />");

            output.Append("Subkey value = " + subkeyValue +

                "<br /><br />");

        }

    }

    else

    {

        output.Append("Value = " + Server.HtmlEncode(aCookie.Value) +

            "<br /><br />");

    }

}

Label1.Text = output.ToString();

 

 

4. 쿠키 (유효) 범위 제어

   쿠키를 저장 하고 난 후 사용할 때 (불러올 때) 에 유요한 범위를 아래와 같이 두 가지 방법으로 제어 할 수 있다.

 

  1. 디렉터리 단위 제어

웹 서버의 특정 디렉터리(폴더)를 기준으로 쿠키의 범위를 제어 할 수 있다.

ASP.NET 의 HttpCookie 에는 Path 속성이 이와 관련된 속성이다.

만일 Path = “/Directory1” 로 설정된 쿠키라면 웹 서버의 ‘/Directory1’ 의 하위 폴더 및 가상 디렉터리에서만 쿠키 값을 읽어 들일 수 있게 되는 것이다. 이외의 폴더 및 루트에 속한 페이지에서는 쿠키를 사용할 수 없다.

Path 속성이 설정되지 않으면 기본적으로 웹 루트인  ‘/’ 가 설정되므로 해당 웹 사이트에서는 모두 사용 가능하게 되는 것이다.

참고> 일부 브라우저 에서는 경로의 대/소문자를 구분한다. 즉 URL 과 Path 속성이 정확히 대/소문자가 일치해야 쿠키를 사용할 수 있다.

 

  1. 도메인 단위 제어

도메인 단위로도 범위 설정이 가능하다.

만일 특정 하위 도메인 에서만 사용가능한 쿠키를 만들고 싶으면 Domain 속성을 지정해 주면 된다.

Mkexp.pe.kr 사이트의 하위 도메인인 sub.mkex.pe.kr 에서만 쿠키를 사용하고 싶으면

Domain = “sub.mkex.pe.kr” 로 설정하면 된다.

또한 mkex.pe.kr 의 모든 하위도메인에서 사용가능 한 쿠키를 만들고 싶으면 Domain = “mkex.pe.kr” 로 설정하면 된다

   

 

 

5. 쿠키 허용 유/무

   클라이언트는 서버에서 제공하는 쿠키를 허용할 지 결정 할 수있다.

   아래 그림은 IE 6.0 에서 쿠키를 차단하는 모습니다.

 

이렇게 되면 웹 서버에서 쿠키를 사용하고 싶어도 할 수 없다.

단, 웹 서버에 쿠키 저장 시 오류는 발생하지 않는다. 다만 클라이언트는 쿠키를 저장하지 않으며 서버 요청 시 쿠키

값도 전달하지 않는 것이다.

 

따라서 쿠키 의존도가 상당히 강한 사이트의 경우 클라이언트의 쿠키 허용 유/무를 판단할 필요가 있다.

그러나 클라이언트의 브라우저가 쿠키를 허용 했는지 안 했는지 한방에 체크 할 수는 없다.

 

Msdn : Cookies 속성은 쿠키 사용 여부를 나타내지 않습니다. 대신 현재 브라우저에서 기본적으로 쿠키를 지원하는

지 여부만 나타냅니다.

 

따라서 msdn 에서 이를 체크 하기 위해 조금은 무식한(?) 방법을 사용한다.

시나리오는 이렇다.

쿠키를 클라이언트에 저장해 한 후 다시 읽어 들여서 읽히면 쿠키가 허용된 것이고 아니면 쿠키가 불허용 된 것이

라 판단하는 것이다. 아래는 msdn 의 샘플 코드이다.

//첫 번째 페이지(쿠키를 작성하고 두 번째 페이지로 리다이렉트 한다.

protected void Page_Load(object sender, EventArgs e)

{

    if (!Page.IsPostBack)

    {

        if (Request.QueryString["AcceptsCookies"] == null)

        {

            Response.Cookies["TestCookie"].Value = "ok";

            Response.Cookies["TestCookie"].Expires =

                DateTime.Now.AddMinutes(1);

            Response.Redirect("TestForCookies.aspx?redirect=" +

                Server.UrlEncode(Request.Url.ToString()));

        }

        else

        {

            Label1.Text = "Accept cookies = " +

                Server.UrlEncode(

                Request.QueryString["AcceptsCookies"]);

        }

    }

}

 

//두 번째 페이지 (쿠키를 읽어보고 허용 유/무를 판단하여 다시 첫번째 페이지로 이동한다)

protected void Page_Load(object sender, EventArgs e)

{

    string redirect = Request.QueryString["redirect"];

    string acceptsCookies;

    if(Request.Cookies["TestCookie"] ==null)

        acceptsCookies = "no";

    else

    {

        acceptsCookies = "yes";

        // Delete test cookie.

        Response.Cookies["TestCookie"].Expires =

            DateTime.Now.AddDays(-1);

    }

    Response.Redirect(redirect + "?AcceptsCookies=" + acceptsCookies,

    true);

}

 

Msdn 이 이러한 두 페이지에 걸친 처리보다는 클라이언트 스크립트로 처리하는 것이 더 좋을 때도 있다.

다음처럼…

<script language="JavaScript">

<!--

function ReadCookie(cookieName) {

var theCookie=""+document.cookie;

var ind=theCookie.indexOf(cookieName);

if (ind==-1 || cookieName=="") return "";

var ind1=theCookie.indexOf(';',ind);

if (ind1==-1) ind1=theCookie.length;

return unescape(theCookie.substring(ind+cookieName.length+1,ind1));

}

 

function SetCookie(cookieName,cookieValue,nDays) {

var today = new Date();

var expire = new Date();

if (nDays==null || nDays==0) nDays=1;

expire.setTime(today.getTime() + 3600000*24*nDays);

document.cookie = cookieName+"="+escape(cookieValue)

                 + ";expires="+expire.toGMTString();

}

//-->

</script>

 

<script language="JavaScript">

<!--

testValue=Math.floor(1000*Math.random());

SetCookie('AreCookiesEnabled',testValue);

if (testValue==ReadCookie('AreCookiesEnabled'))

     document.write('<b>현재고객님의 브라우져에는 쿠키가허용되어있습니다.</b>')

else document.write('<b>현재 고객님의 브루우져에 쿠키허용이 금지되어있습니다. </b>')

//-->

</script>

 

이 스크립트 코드는 asp.net 에서의 체크 시나리오와 동일하다. 단지 클라이언트에서 실행되는 것이라서 불 필요한

라운드 트립 이 발생하지 않는다는 장점이 있다.

샘플 코드의 해석은 중요치 않다. 단지 이러한 방법으로 확인하는 시나리오가 있을 수 있다는 것이 중요하다.

 

 

6. 기타 참고 사항

 쿠키는 http 프로토콜의 헤더에 포함되어 진다.

 

  아래 그림은 쿠키를 저장할 때의 http 헤더 정보이다.

 

그리고 다음은 클라이언트가 쿠키 값을 서버로 전송하는 http 헤더 정보이다.

 

자세한 http 헤더 정보는 다음 링크에서 확인 하자.

HTTP 프로토콜 - http 헤더

 

 

또한 하위 키가 있는 쿠키의 정보 변경 시 주의할 사항에 대해서는 다음 링크에서 확인 하자.

ASP.NET에서 다중쿠키 수정 시 주의점

 

 

7. 쿠키.. 보안에 유의 하라.

   쿠키는 정보 유지를 위해 클라이언트에 의존 하는 편하고도 좋은 방법이다.

   그러나 모든 것은 얻는 것이 있으면 잃는 것 또한 있는 법이다.

   기본적으로 쿠키는 클라이언트 pc에 txt 파일 형태로 저장되기 때문에 보안상 좋지 않다.

   만일 중요한 정보를 평문 형태로 저장 한다면 이건 거의 자살행위나 마찬 가지다.

   또한 적절한 암호화를 수행했다고 하여도 안정성은 보장 할 수 없다.

   나아가 Key=Value 형태를 그대로 저장하는 것에도 문제가 있다.

  

   가장 기본은 중요한 정보는 쿠키에 의존하면 안 된다 이다.

   그러나 만일 불가피하게 약간은 중요한 정보를 쿠키에 저장해야만 할 경우에는 적절한 암호화를 수행하도록 한다.

   또한 key=value 패턴을 사용하지 않도록 한다. 그리고 악의의 사용자가 특정 범위를 쉽게 알아내어 복호화 하는 것

   을 미연에 방지하도록 한다.

 

쿠키 변조와 관련된 내용은 아래 링크에서 확인 하자.

  

->[웹 보안 시리즈] 6. 데이터 변조 ? 쿠키 변조

댓글 보기
이 름 입력일 수정

zxcas 2022-11-06
나는미술시간이제일좋았다주제도재료도뭐든지좋았다내가마리안느보다잘할수있는유일한과목이었다그래봤자나는A를받았고마리는B를받았지만마리안느는그예쁜얼굴만큼이나완벽한성적표를가지고있었다그것도입학이후로쭉마리가원하는대학교라면아마도어디든지갈수있을것이다나는슬그머니올라오는질투심을꾹눌러내리고내옆에서수채화를그리고있는마리를쳐다봤다마리는평소의가볍고천진한표정에서꽤진지한얼굴로물의양을조절하고있었다꽃과나무열매를묘사한그림이었다몇겹으로칠해져완성이곧이었다마리의왼쪽팔이곧물통을건드릴것같았다나는곧벌어질일을예상할수있었지만내그림을슬그머니옆으로옮기는것외에다른일은하지않았다그리고물통이쏟아졌다온갖색의물감이섞여구정물처럼보이는물이마리안느의그림위로곧장마리는얼른종이를빼냈지만너무늦었다종이를빼낼때더러운물이팍튀었다나는그제야얼른일어나친한친구로서바닥에쏟아진물을닦아줬다마리는꽤상심한것처럼보였다눈썹에힘이풀려축처져있었으니까나는동정과질투심을동시에느꼈다그리고어쩌면이일을통해서마리와좀더가까워질수도있겠다는생각을했다걱정하지마학교끝나고내가도와줄까나는개수대근처에서마리안느에게속삭였다마리는천천히고개를끄덕였다그녀의얼굴은아주섬세하고극적이게염려의빛을띠고있었다나는상아나밀랍으로만들어낸것같은그얼굴이못내아름답고거북해서얼굴을돌렸다마리는우리집으로오는동안끊임없이무언가에대해서조잘거렸다나는마리의쾌활한목소리가좋아서그와비슷한톤으로맞장구를쳐줬다하지만가십거리도곧동났다우리둘은조용히걸었다나는우리집이가까워지자마리를봤다아무말도없이걸어가는마리안느는허리와어깨를무용수처럼곧게펴고있었지만어쩐지표정에서연약함이묻어났다어딘가막연한갈곳없는애들이나지을법한표정이었다나는그때그것이그저가볍고섹시한여자애들특유의무심하고텅빈표정일거라고생각했다내시선을느낀마리가나를향해엷게웃었다나는왜인지마음이약해졌다우리집에지금아무도없어엄마든아빠든오빠든9시는되어야오기시작할테니까그래잘됐네그리고마리는핸드폰을보며걷기시작했다나는마리안느의방금처럼상냥하고나약한모습을다른애도봤을지궁금해졌다아마그렇겠지습관적으로만들어진표정이었을테니까집은역시조용했다우리는곧장내방으로들어가서스케치를시작하기로했다물론내가마리의화풍을흉내내서더멋지고정교하게대신해줬다마리는계속핸드폰을들여다보고있었다나는마리가보고듣는이야기들을나에게도말해주기를원했다마리학교밖에서보니까좀달라보여뭐마리가어이없다는듯이웃으며내의자를향해쿠션을집어던졌다우리는동

| | 목록으로