document.cookie 객체의 구조
자바스크립트에서는 document.cookie 객체를 통해 쿠키에 접근할 수 있습니다. 이 객체는 대입연산자를 통해 새로운 값을 내부 쿠키 리스트에 추가할 수 있습니다.
[code javascript;gutter:false] document.cookie = "ID=123456789";
document.cookie = "PW=abcdefghi"; [/code]
위와 같은 자바스크립트를 수행하면 일반적인 대입문처럼 쿠키명 ID가 없어지는 것이 아니라 내부 쿠키 리스트에 ID라는 쿠키와 PW라는 쿠키가 추가될 것입니다. 만약 쿠키명이 일치하는 것이 내부 쿠키 리스트에 있었다면 새로운 값으로 대치될 것입니다.
이미 생성되어 있는 쿠키를 참조하려면 document.cookie 객체를 문자열처럼 다루면 됩니다. 이 문자열은 쿠키명과 쿠키값으로 구성되어 있습니다. 각 쿠키명과 쿠키값은 등호(=)로 구분되어 있고, 각각의 쿠키는 세미콜론(;)으로 구분되어 있습니다. 위와 같이 쿠키가 생성되었을 때 document.cookie 객체를 참조하면 "ID=123456789;PW=abcdefghi"라는 문자열을 얻을 수 있습니다. 이 문자열을 가지고 문자열 메소드인 indexOf() 또는 substring() 함수를 이용하면 각 쿠키에 대한 정보를 분리할 수 있을 것입니다. 이러한 예는 아래에 있는 사용자 정의 함수 getCookie()를 참조하기 바랍니다.
PHP에서와 마찬가지로 유효한 도메인과 유효한 경로에서 만들어 낸 쿠키 정보만이 document.cookie을 통해서 볼 수 있습니다.
document.cookie 객체를 직접 사용할 수도 있지만, 대부분 아래와 같이 미리 정의된 함수 setCookie(), getCookie(), delCookie()를 통해 쿠키를 다루게 됩니다.
쿠키 설정하기
PHP의 setcookie() 함수와는 달리 expires(유효기간) 매개변수의 단위는 천분의 일초단위로 설정합니다. secure가 다소 다르기는 하지만 다른 매개변수는 PHP와 별다르지 않습니다. 저장된 쿠키 정보를 보면 문자열 소스 차원에서 PHP에서 다룰 때와 동일하지 않습니다. 왜냐하면 PHP에서 인코딩/디코딩하는 방식과 자바스크립트에서 인코딩/디코딩하는 방식이 다르기 때문입니다. 따라서 양쪽의 함수를 혼용하여 사용하는데는 문제가 있으니 주의하기 바랍니다. 여기에 정의된 setCookie() 함수는 "Designing Dynamic Web Pages with JavaScript"의 저자 Nick Heinle의 작품을 변형시킨 것입니다. 본래의 함수는 서적을 참조하시기 바랍니다. 이 원서에 대한 번역서는 "자바스크립트로 다이나믹 웹페이지 디자인하기"라는 제목으로 나와 있습니다.
[code javascript;gutter:false] function setCookie(name, value, expires, path, domain, secure) {
secure = (secure == null) ? false : secure;
var exp = new Date();
exp.setTime(expires);
document.cookie = name + "=" + escape(value)
+ ((expires == null) ? "" : ("; expires=" + exp.toGMTString()))
+ ((path == null) ? "" : ("; path=" + path))
+ ((domain == null) ? "" : ("; doamin=" + domain))
+ ((secure == true) ? "; secure" : "");
} [/code]
예를 들어 아래와 같이 각 매개변수를 지정할 수 있으며, 이 때 유효기간은 1시간이 됩니다.
[code javascript;gutter:false] setCookie(
"mycookie", // 쿠키명
"cookie_value", // 쿠키값
exp.getTime()+1000*3600, // 유효 기간
"/exam", // 유효 디렉토리
".phpclass.com" // 유효 도메인
); [/code]
쿠키 정보 읽어오기
쿠키명과 값은 document.cookie 객체에 통해 참조될 수 있습니다. 자바스크립트가 저장하는 쿠키의 형태는 아래와 같으며 각각의 name=value 쌍은 세리콜론과 공백으로 구분되어지고 제일 마지막 값에는 세미콜론이 없습니다.
[code javascript;gutter:false] name1=value1; name2=value2; name3=value3 [/code]
쿠키의 값을 좀 더 쉽게 얻기 위해 다음과 같이 getCookie() 함수를 정의하여 사용합니다. 이 함수는 Nick Heinle의 작품을 그대로 가져왔습니다.
[code javascript;gutter:false] // Heinle's function for retrieving a cookie.
function getCookie(name) {
var cname = name + "=";
var dc = document.cookie;
if (dc.length > 0) {
begin = dc.indexOf(cname);
if (begin != -1) {
begin += cname.length;
end = dc.indexOf(";", begin);
if (end == -1)
end = dc.length;
return unescape(dc.substring(begin, end));
}
}
return null;
} [/code]
이 함수는 단지 쿠키명만 지정하여 주면 document.cookie 객체를 검사하여 해당 쿠키의 값을 되돌려 줍니다. 저장된 쿠키가 없는 경우에는 null 값을 되돌려 줍니다.
[code javascript;gutter:false] value = getCookie ("mycookie"); [/code]
쿠키 삭제하기
마지막으로 쿠키를 삭제할 수 있는 함수 delCookie()를 살펴보겠습니다. 이 함수는 쿠키 센추럴(www.cookiecentral.com)에 있는 Dorcht의 함수를 그대로 가져왔습니다.
[code javascript;gutter:false] function delCookie (name, path, domain) {
if (getCookie(name)) {
document.cookie = name + "="
+ ((path == null) ? "" : "; path=" + path)
+ ((domain == null) ? "" : "; domain=" + domain)
+ "; expires=Thu, 01-Jan-70 00:00:01 GMT";
}
} [/code]
delCookie() 함수는 쿠키 파일에서 쿠키를 삭제하기 위해 사용되는 함수이다. delCookie() 함수를 사용하기 위해서는 보통 쿠키명만 넘겨주면 된다. 그러나 setCookie() 함수에서 쿠키를 구울 때 path와 domain을 지정하였으면, delCookie() 함수로 지울 때도 동일할 path와 domain을 분명히 지정해 주어야 합니다. 예를 들어, "mycookie" 쿠키에 대한 정보는 다음과 같이 지울 수 있습니다.
[code javascript;gutter:false] delCookie("mycookie", "/exam", ".phpclass.com"); [/code]
구두점 인코딩/디코딩
브라우저가 등호(=)와 세미콜론(;)을 각 쿠키를 분리시키는 구분자로 사용하기 때문에, 이것들은 자신이 저장하는 텍스트안에 넣을 수가 없습니다. 이러한 특수 코드를 쿠키값에 저장하려면 document.cookie 객체에 문자열을 넘기기 전에 escape()를 사용하여 인코딩해야 하고, unescape()를 사용하여 복구하여야 합니다.
escape() 함수
일반문자를 ASCII 형식(URL 형식; 폼에서 보내어진 %가 붙은 문자) 문자로 변환합니다. 예를 들어 아래와 같이 "ASCII &? 문자"라는 문자열을 escape() 함수로 넘겨주면 "ASCII%20%26%3F%20%uBB38%uC790"라는 문자열을 되돌려 받습니다.
[code javascript;gutter:false] var encode = escape("ASCII &? 문자"); [/code]
unescape() 함수
ASCII 형식(URL 형식) 문자를 일반문자로 변환합니다. 예를 들어 아래와 같이 "ASCII%20%26%3F%20%uBB38%uC790"라는 문자열을 unescape() 함수로 넘겨주면 "ASCII &? 문자"라는 문자열을 되돌려 받습니다.
[code javascript;gutter:false] var decode = unescape("ASCII%20%26%3F%20%uBB38%uC790"); [/code]

'phpsource > 캐시&세션&쿠키' 카테고리의 다른 글

넷스케이프의 쿠키에 관한 예비 규격서(복사본)  (0) 2001.02.21
{쿠커}9.쿠커  (0) 2001.02.20
{쿠커}7.setcookie() 함수  (0) 2001.02.20
{쿠커}6.쿠키 다루기  (0) 2001.02.20
{쿠커}5.쿠키 규격  (0) 2001.02.20
Posted by 방글24
PHP에서의 쿠키
PHP가 거의 완벽하게 쿠키를 지원하기 때문에 쿠키를 이용하기 위해 이해하기 어려운 요구헤더나 응답헤더를 이해할 필요가 없습니다. 쿠키를 생성할 때는 setcookie() 함수를 사용합니다. 쿠키를 생성할 때 필요로 하는 옵션들 - 유효기간, 유효경로, 유효도메인, 보안설정 - 은 setcookie() 함수의 매개변수로 전달하면 됩니다. PHP 내에서 쿠키를 읽는 것은 변수를 액세스하는 것처럼 간단합니다. PHP 스크립트를 시작할 때 쿠키들은 자동적으로 전역변수로 사용되도록 만들어집니다. 예를 들어, 쿠키명이 "ID"이고 쿠키값이 "123456789"라면 쿠키명 "ID"에 해당하는 전역변수 $ID에 "123456789"라는 값이 저장되어 있을 것입니다. 때에 따라서는 $ID라는 전역변수대신에 $HTTP_COOKIE_VARS["ID"]라는 전역배열변수를 가지고 다룰 수 있습니다.
쿠키 설정하기
PHP에서는 setcookie() 함수를 이용하여 쿠키를 설정할 수 있습니다. PHP에서 쿠키를 생성하는 함수 setcookie()의 정의는 다음과 같으며, 이 중에 name를 제외한 나머지 매개변수는 모두 생략할 수 있습니다.
int setcookie(string name, string [value],
                                      int [expire],
                                      string [path],
                                      string [domain],
                                      int [secure]);
생략할 수 있는 매개변수에 대한 기본값은 빈문자열(value, path, domain)이거나 0(expire, secure)입니다. 예를 들어, 만약 expire와 path는 기본값을 사용하고 domain만 새로이 지정하고자 한다면 다음과 같이 사용할 수 있습니다.
[code php;gutter:false] setcookie("name", "value", 0, "", ".phpclass.com"); [/code]
구분 매개변수명 기본값 동작
쿠키의 유효기간 expires 0 사용자가 브라우저를 종료할 때 쿠키가 없어짐
쿠키의 유효 디렉토리 path 웹문서 경로 웹문서가 존재하는 디렉토리
쿠키의 유효 도메인 domain 지정안함 쿠키를 설정한 서버의 도메인
쿠키의 보안 secure 지정안함 Disabled
name & value
첫 번째 매개변수 name은 설정할 쿠키명이고 value는 그 쿠키에 저장될 이름입니다. 자세한 것은 앞장 "쿠키 규격"을 참조바랍니다.
유효기간 설정하기
세 번째 매개변수 expire는 쿠키 유효기간을 설정하는 함수이며, 정수형으로서 표준 유닉스 시간을 그 값으로 갖습니다. 유효기간은 반드시 타임스탬프(1970년 1월 1일 이후 시간을 초로 표시)로 지정됩니다. 이 타임스탬프는 PHP에서 time()과 mktime() 함수들을 사용하여 계산할 수 있습니다. time() 함수는 현재 시간을 타임스탬프로 리턴하며, mktime() 함수는 사람들에게 익숙한 형식의 날짜(예를 들어, Tue, 06 Feb 2001 12:57:21 GMT)를 타임스탬프로 변환해 줍니다. time() 함수와 mktime() 함수에 의해 계산된 시간은 웹서버 시간에 따라 계산되는데 반하여 쿠키의 유효기간은 웹서버가 아닌 클라이언트 시스템 상에서의 시간이며, 따라서 웹서버와 서로 다른 시간대에 있을 수 있습니다. 기본값인 0은 오직 현재 방문자의 브라우저 세션을 위해서 설정되며, 방문자가 브라우저를 닫으면 만료됩니다. 브라우저를 종료하더라도 계속 쿠키가 존재하기 위해서는 유효기간을 명시하여야 합니다.
[code php;gutter:false] // 3600초(1시간) 이후에 만료된다.
setcookie("mycookie", $value, time()+3600);

// 2002년 1월 1일에 만료된다.
setcookie("mycookie", $value, mktime(0,0,0,1,1,2002));

// 2020년 5월 12일 오후 6:30분에 만료된다.
setcookie("mycookie", $value, mktime(18,30,0,5,12,2020)); [/code]
이와 같이 유효기간을 지정하게 되면 브라우저를 종료한 뒤 다시 실행하더라도 그대로 보존되며, 지정된 시간이 되면 자동적으로 그 쿠키를 제거할 것입니다.
유효경로 지정하기
이 매개변수를 생략하는 경우에는 setcookie() 함수를 호출한 웹문서가 있는 디렉토리와 이 디렉토리의 하위 디렉토리에서만 쿠키값을 참조할 수 있게 됩니다. 따라서 PHP4 세션함수에서 사용되는 쿠키와 같이 모든 서버상의 모든 디렉토리에서 유효한 쿠키를 사용하려면 path 매개변수의 값으로 루트 디렉토리를 설정하여야 합니다. 즉, 세션함수에서의 쿠키는 "/"가 기본값이지만 setcookie() 함수에서의 기본값은 현재 디렉토리가 됩니다.
[code php;gutter:false] setcookie("mycookie", "cookie_value", 0, "/"); [/code]
"관련서적(?)"을 보다보면 이 부분에서 다소 상이하다는 것을 알 수 있습니다. 관련서적에는 기본 동작이 "/"로 서버상의 모든 디렉토리가 유효하다고 되어 있습니다. 그러나 이는 앞의쿠키 규격에서 보았듯이 HTTP 응답헤더 Set-Cookie에 유효경로를 지정하지 않으면 웹문서가 존재하는 디렉토리 및 그 하위 디렉토리에서만 유효한 쿠키가 만들어지게 됩니다. 관련서적 저자는 세션함수와 혼동하지 않았나 생각합니다. 세션함수에서 사용하는 쿠키의 유효경로는 "/"로 되어 있습니다. 물론 php.ini의 옵션 session.cookie_path에 설정된 값이 기본값이 되는 것이지요.
유효도메인 지정하기
복수 도메인에 쿠키를 사용하기 위해서는 아래와 같이 도메인의 앞쪽 부분을 생략하여 지정하여야 합니다. ".phpclass.com"라고 지정하면 www.phpclass.com, hwooky.phpclass.com, ..... 와 같이 뒤쪽이 일치하는 모든 도메인에서 쿠키를 사용할 수 있습니다. 그러나 www.phpclass.net라는 도메인에서는 쿠키를 사용할 수 없습니다.
[code php;gutter:false] setcookie("mycookie", "cookie_value", $expire, $path, ".phpclass.com"); [/code]
이것은 호스트 이름이 phpclass.com 도메인에 있는 모든 서버들로 쿠키를 전송하도록 브라우저에 알립니다.
쿠키의 보안 지정하기
타인으로부터 보호해야 할 민감한 정보가 쿠키에 포함되어 있을 때에 지정할 수 있는 매개변수입니다. 서버가 SSL(Secure Sockets Layer)을 지원할 때만 쿠키를 전송합니다.
배열값 쿠키 설정하기
도메인당 쿠키는 최대 20개까지 저장할 수 있다는 것은 앞에서도 언급한 바 있습니다. 그런데 관련서적을 보면 배열을 이용하면 여러 개의 값들을 하나의 쿠키에 저장시킬 수 있다고 되어 있습니다. 즉, 쿠키를 하나의 배열로 다루고, 그 배열에 있는 각 구성 요소에 값을 지정하는 것입니다. 그리고 이러한 경우의 예를 아래와 같다고 하였습니다. 아래의 예제들은 거의 모두 PHP 3.0.14에서 실험한 결과입니다.
[code php;gutter:false] if (!isset($mycookie[0])) {
setcookie("mycookie[0]", "hwooky");
}

$mycookie[1]++;
setcookie("mycookie[1]", $mycookie[1]);

echo ("Hello $mycookie[0], you've seen this page " .
$mycookie[1] . ($mycookie[1] == 1 ? " time!" : " times!")); [/code]
그러나 위와 같은 방법으로 배열 각 요소를 쿠키에 저장하게 되면 역시 각 배열 요소가 하나의 쿠키로 저장되기 때문에 20개가 넘는 배열 요소를 저장할 수 없습니다. 아래는 이 때 생성되는 쿠키입니다.
mycookie[1]
7
www.safety.katri/exam2/cookie/
0
2023223680
29397420
3081596640
29397410
*
mycookie[0]
hwooky
www.safety.katri/exam2/cookie/
0
1993223680
29397420
3054096640
29397410
*
그러면 실제로 20개가 넘는 배열 요소를 가지고 위와 같은 방법으로 쿠키를 구워 보도록 하죠. 아래는 이러한 경우의 예입니다.
[code php;gutter:false] <?php

for ($i=0;$i<26;$i++)
setcookie("cookie[$i]", "$i");

if (!isset($cookie)) {
echo "<META http-equiv='Refresh' content='0; URL=$PHP_SELF'>";
exit;
}

?>

<P>document.cookie에서 확인한 쿠키정보</P>
<SCRIPT language=JavaScript>
<!--
cookie_str = document.cookie;
while (-1 != cookie_str.indexOf(';')) {
current = cookie_str.substring(0, cookie_str.indexOf(';')+1);
cookie_str = cookie_str.substring(cookie_str.indexOf(';')+1);
document.write(current + '\n');
}
document.write(cookie_str + '\n');
//-->
</SCRIPT> [/code]
위 소스코드를 실행하면 아래와 같이 20개의 배열요소만 쿠키에 저장되어 있는 것을 확인할 수 있습니다. 여기서 하나 더 주의깊게 살펴볼 것이 있습니다. 쿠키를 구워낸 순서와 반대로 저장된다는 것입니다. 이것은 PHP3에서의 결과이며 뒤에서도 언급하겠지만 PHP4에서는 이 순서가 뒤바뀌게 됩니다.
document.cookie에서 확인한 쿠키정보

cookie[19]=19;
cookie[18]=18;
cookie[17]=17;
cookie[16]=16;
cookie[15]=15;
cookie[14]=14;
cookie[13]=13;
cookie[12]=12;
cookie[11]=11;
cookie[10]=10;
cookie[9]=9;
cookie[8]=8;
cookie[7]=7;
cookie[6]=6;
cookie[5]=5;
cookie[4]=4;
cookie[3]=3;
cookie[2]=2;
cookie[1]=1;
cookie[0]=0
쿠키를 구워낼 때 배열 요소 대신에 배열명을 지정하면 어떻게 될까요? 지금부터 알아보도록 하겠습니다.
[code php;gutter:false] <?php

if (!isset($mycookie)) {
$mycook = array("mycook1"
, "mycook2"
, "mycook3"
, "mycook4"
, "mycook5"
, "mycook6"
, "mycook7"
, "mycook8"
, "mycook9"
, "mycook10"
, "mycook11"
, "mycook12"
, "mycook13"
, "mycook14"
, "mycook15"
, "mycook16"
, "mycook17"
, "mycook18"
, "mycook19"
, "mycook20"
, "mycook21"
, "mycook22"
, "mycook23"
, "mycook24"
, "mycook25"
);

setcookie("mycookie", $mycook, time()+3600);
die("<META http-equiv='Refresh' content='0; URL=$PHP_SELF'>");
} else {
setcookie("mycookie", "", time()-3600*24*365);
if (is_array($mycookie))
while (list($name,$value)=each($mycookie))
echo "$name=$value\n";
else
echo "(no array)$mycookie\n";
}

?> [/code]
실행 결과는 아래와 같습니다.
(no array)Array
서버에서 받은 쿠키를 확인하면 배열값이 넘어오는 것이 아니라 단순 문자열 "Array"가 넘어온다는 것을 알 수 있습니다. 그럼 실제로 로컬 시스템에 저장된 쿠키는 어떻게 되었을까요? 그것을 알아보기 위해 로컬시스템에 저장된 쿠키파일을 살펴보았습니다. 아래는 위의 소스를 익스 5.0에서 실행한 후에 "c:\windows\cookies\hwooky@cookie[1].txt"에 저장된 쿠키 파일 내용입니다.
mycookie
Array
www.safety.katri/exam2/cookie/
0
2298062848
34459487
537668192
29397773
*
첫번째 줄의 mycookie가 쿠키명이고, Array가 쿠키값입니다. 각 배열요소값은 저장되지 않고 setcookie("mycookie", $mycook, time()+3600)를 이용해 쿠키를 만들 때 값으로 지정된 배열변수 $mycook의 변수형만 쿠키파일에 저장되는 것을 볼 수 있습니다. 그러면 쿠키를 서버에서 클라이언트로 보낼 때 배열요소값은 생략하고 변수형 "Array"라는 문자열만 보낸 것이 아닐까요? 서버에서 클라이언트로 쿠키를 보낼 때 쿠키정보를 응답헤더에 첨부해서 보낸다는 것은 앞장에서 살펴보았습니다. 그래서 실제로 어떤 정보를 응답헤더에 첨부해서 클라이언트로 보내는지 확인하기 위해 응답헤더를 직접 확인하였습니다. 아래는 위의 소스를 실행할 때 발생하는 응답헤더를 모니터링한 것입니다.
http/1.1 200 ok:
date: Tue, 06 Feb 2001 12:57:21 GMT
server: Apache/1.3.14 (Unix) PHP/4.0.3pl1 PHP/3.0.14
x-powered-by: PHP/3.0.14
set-cookie: mycookie=Array; expires=Tuesday, 06-Feb-01 13:57:21 GMT
connection: close
content-type: text/html
위의 응답헤더를 보면 알겠지만 클라이언트로 보내는 쿠키정보에는 $mycook 변수형만 첨부되어 있지 배열요소는 클라이언트로 보내지 않는다는 것을 알 수 있습니다. 이를 다시 확인하기 위해 브라우저에서 서버로 보내지는 환경변수 "HTTP_COOKIE"를 확인하여 보겠습니다. 브라우저에 있는 쿠키 정보는 요구헤더를 통해 웹서버로 전달되며 웹서버가 요구헤더를 이용하여 환경변수 "HTTP_COOKIE"를 설정하도록 되어 있습니다. 요구헤더에 포함된 쿠키정보의 구조에 대하여는 앞장에서 살펴보았습니다.
[code php;gutter:false] <?php

if (!isset($mycookie)) {
$mycook = array("mycook1"
, "mycook2"
, "mycook3"
, "mycook4"
, "mycook5"
, "mycook6"
, "mycook7"
, "mycook8"
, "mycook9"
, "mycook10"
, "mycook11"
, "mycook12"
, "mycook13"
, "mycook14"
, "mycook15"
, "mycook16"
, "mycook17"
, "mycook18"
, "mycook19"
, "mycook20"
, "mycook21"
, "mycook22"
, "mycook23"
, "mycook24"
, "mycook25"
);

setcookie("mycookie", $mycook, time()+3600);
die("<META http-equiv='Refresh' content='0; URL=$PHP_SELF'>");
} else {
setcookie("mycookie", "", time()-3600*24*365);
if (is_array($mycookie))
while (list($name,$value)=each($mycookie))
echo "$name=$value\n";
else
echo "ENV=[".getenv("HTTP_COOKIE")."]\n";
}

?> [/code]
위 소스의 실행 결과는 다음과 같습니다. 실행 결과를 보면 알겠지만 환경변수 "HTTP_COOKIE"를 통해 전달되는 쿠키정보는 "mycookie=Array"이 전부입니다. 결국 배열 $mycook의 값을 쿠키로 굽더라도 브라우저에 저장된 쿠키값은 배열요소 전부가 아니라 변수형 "Array"만 쿠키파일에 저장된다는 것을 알 수 있습니다.
ENV=[mycookie=Array]
이러한 현상은 setcookie() 함수 대신에 아래와 같이 직접 header() 함수를 이용할 때도 동일하게 나타납니다.
[code php;gutter:false] $expires = gmdate("D, j-M-Y H:i:s", time() + 3600)." GMT";
header("Set-Cookie: mycookie=$mycook; expires=$expires"); [/code]
쿠키정보를 브라우저로 보내려면 setcookie() 함수를 이용하지만 PHP 스크립터 내부에서는 최종적으로 php3_header() 함수를 통해 응답헤더의 일부로 쿠키정보를 브라우저에 전달합니다. 아래는 PHP3.0.14 소스파일 head.c에 있는 아파치 웹서버에 대한 php3_header() 함수를 요약한 것입니다.
[code c;gutter:false] /*
소스 파일 위치 : ......\php-3.0.14\functions\head.c
*/

PHPAPI int php3_header(void)
{
......(중간생략)......

cookie = php3_PopCookieList();
while (cookie) {
if (cookie->name)
len += strlen(cookie->name);
if (cookie->value) {
cookievalue = _php3_urlencode(cookie->value, strlen (cookie->value));
len += strlen(cookievalue);
}

......(중간생략)......

tempstr = emalloc(len + 100);
if (!cookie->value || (cookie->value && !*cookie->value)) {

......(중간생략)......

} else {
/* FIXME: XXX: this is not binary data safe */
sprintf(tempstr, "%s=%s", cookie->name, cookie->value ? cookievalue : "");
if (cookie->name) efree(cookie->name);
if (cookie->value) efree(cookie->value);
if (cookievalue) efree(cookievalue);
cookie->name=null;
cookie->value=null;
cookievalue=null;
if (cookie->expires > 0) {
strcat(tempstr, "; expires=");
dt = php3_std_date(cookie->expires);
strcat(tempstr, dt);
efree(dt);
}
}
if (cookie->path && strlen(cookie->path)) {
strcat(tempstr, "; path=");
strcat(tempstr, cookie->path);
efree(cookie->path);
cookie->path=null;
}
if (cookie->domain && strlen(cookie->domain)) {
strcat(tempstr, "; domain=");
strcat(tempstr, cookie->domain);
efree(cookie->domain);
cookie->domain=null;
}
if (cookie->secure) {
strcat(tempstr, "; secure");
}
table_add(GLOBAL(php3_rqst)->headers_out, "Set-Cookie", tempstr);
if (cookie->domain) efree(cookie->domain);
if (cookie->path) efree(cookie->path);
if (cookie->name) efree(cookie->name);
if (cookie->value) efree(cookie->value);
if (cookievalue) efree(cookievalue);
efree(cookie);
cookie = php3_PopCookieList();
efree(tempstr);
}
GLOBAL(php3_HeaderPrinted) = 1;
GLOBAL(header_called) = 1;
send_http_header(GLOBAL(php3_rqst));

......(중간생략)......

}

......(중간생략)......

GLOBAL(header_is_being_sent) = 0;
return(1);
} [/code]
위 함수에는 응답헤더에 포함되는 쿠키 정보 문자열 "set-cookie: mycookie=Array; expires=Tuesday, 06-Feb-01 13:57:21 GMT"을 만드는 과정이 나와 있고 최종적으로는 모든 작성된 쿠키 정보 문자열들을 브라우저로 전송(함수 send_http_header)하는 것으로 함수가 종료됩니다. 함수를 분석해 보면 _php3_urlencode(cookie->value, strlen (cookie->value))에 의해 배열에 대한 쿠키값이 "Array"로 변환되는 것을 볼 수 있고 배열요소가 쿠키 정보 문자열에 포함되지 않는다는 것을 알 수 있습니다. 여기에서 배열요소는 모두 사라지게 되는 것입니다.
하나의 쿠키에 배열을 담기 위한 노력
배열요소가 20개 이상 존재한다면 그대로 쿠키로 저장할 수는 없습니다. 이때는 배열을 직렬화(serialize)하여 하나의 문자열로 만든 다음 이 문자열을 쿠키로 만드는 것입니다. 쿠키를 읽어 들일 때는 반대로 문자열을 원래의 배열로 만들기 위해 unserialize 하는 것입니다. 이러한 방법은 세션함수에서 이용하는 방법으로 가장 신뢰성있는 방법입니다.
[code php;gutter:false] <?php

if (!isset($mycookie)) {
$mycook = array("mycook1"
, "mycook2"
, "mycook3"
, "mycook4"
, "mycook5"
, "mycook6"
, "mycook7"
, "mycook8"
, "mycook9"
, "mycook10"
, "mycook11"
, "mycook12"
, "mycook13"
, "mycook14"
, "mycook15"
, "mycook16"
, "mycook17"
, "mycook18"
, "mycook19"
, "mycook20"
, "mycook21"
, "mycook22"
, "mycook23"
, "mycook24"
, "mycook25"
);

$value = serialize($mycook);
setcookie(
"mycookie",
get_magic_quotes_gpc() ? $value : addslashes($value),
time+3600
);
die("<META http-equiv='Refresh' content='0; URL=$PHP_SELF'>");
} else {
setcookie("mycookie", "", time()-3600*24*365);
$mycook = unserialize(stripslashes($mycookie));
if (is_array($mycook))
while (list($name,$value)=each($mycook))
echo "$name=$value\n";
else
echo "ENV=[".getenv("HTTP_COOKIE")."]\n";
}

?> [/code]
위에서 get_magic_quotes_gpc()를 이용하는 부분이 있을 것입니다. php.ini 설정 파일에 있는 옵션 magic_quotes_gpc의 설정상태에 따라 적절히 처리해 주지 않으면 저장된 쿠키를 제대로 읽을 수가 없습니다. 제가 공개한 세셔너 또는 쿠키 관련 자료들이 제대로 동작하지 않는다면 이 부분을 의심해 보아야 합니다. 제가 실험한 웹서버의 환경에서는 magic_quotes_gpc의 값이 ON으로 설정되어 있기 때문에 저장된 값에는 '(single-quote), "(double-quote), \(backslash), 널(NUL) 들의 앞에 백슬래시가 자동으로 붙게 됩니다. 따라서 이러한 경우에는 쿠키를 읽을 때 반드시 stripslashes() 함수를 이용하여 자동으로 붙은 백슬래시를 제거해야 합니다. 그런데 여러분의 웹서버 환경에서 magic_quotes_gpc의 값이 OFF로 되어 있다면 제가 공개한 자료들이 실행에 문제가 생길 수 있습니다. 단순한 숫자나 영문자로 구성된 쿠키값일 때는 관계없으나 serialize() 함수로 직렬화된 문자열의 경우는 꼭 문제가 생기지요. get_magic_quotes_gpc() 부분을 삽입한 것은 웹서버의 설정상태에 관계없이 동작시키기 위해 작성된 것이니 참조바랍니다.
위 소스의 실행 결과는 다음과 같습니다. 이제야 제대로 배열이 저장되는 것 같네요.
0=mycook1
1=mycook2
2=mycook3
3=mycook4
4=mycook5
5=mycook6
6=mycook7
7=mycook8
8=mycook9
9=mycook10
10=mycook11
11=mycook12
12=mycook13
13=mycook14
14=mycook15
15=mycook16
16=mycook17
17=mycook18
18=mycook19
19=mycook20
20=mycook21
21=mycook22
22=mycook23
23=mycook24
24=mycook25
쿠키 사용을 위한 PHP 설치 옵션
쿠키로부터 전달받은 값이 서버 설치 옵션에 따라 전역변수로 받을 수도 있고 전역배열변수 $HTTP_COOKIE_VARS[]로 받을 수도 있습니다.
그런데 $HTTP_COOKIE_VARS[]을 언제나 사용할 수 있는 것은 아니고, PHP를 서버에 설치할 때 지정한 옵션에 따라 달라지지요. $HTTP_COOKIE_VARS[]와 관련된 서버 세팅은 두가지입니다. 하나는 소스 컴파일할 때 "--enable-track-vars"라는 설정옵션을 지정하여야 합니다. 두번째는 "--enable-track-vars"를 지정하여 소스 컴파일을 하더라도 php.ini 파일에 있는 track_vars 지시자에 의해 $HTTP_COOKIE_VARS[]를 Enable 할 수도 있고 Disable 할 수도 있습니다. 아래와 같이 track_vars 지시자를 Enable 하십시요.
php.ini의 내용중
================

track_vars = On ; enable the $HTTP_*_VARS[] arrays, where * is one of
; ENV, POST, GET, COOKIE or SERVER.
만약 여러분의 서버가 "--enable-track-vars"를 지정하여 소스 컴파일되어 있지 않다면 PHP_COOKIE_VARS를 사용하시기 전에 문서 최상단에 아래와 같이 php_track_vars 지시자를 사용하세요.
[code php;gutter:false] <?php_track_vars?>
<?php
.
.
.
?> [/code]
주의할 점은 php_track_vars 지시자가 PHP3에서만 제대로 동작되며, PHP4부터는 php_track_vars 지시자를 사용하지 않습니다. PHP4에서 track_vars 의 설정값이 "1"일 때에 php_track_vars 지시자를 사용하게 되면 아래와 같은 에러가 발생합니다.
Warning: <?php_track_vars?> is no longer supported
- please use the track_vars INI directive instead in ...... on line ???
PHP 4.0.3부터는 track_vars가 자동적으로 (항상) ON 상태입니다. 따라서 PHP 4.0.3부터는 php.ini의 track_vars의 설정 상태에 관계없이 php_track_vars 지시자를 사용하면 무조건 위와 같은 에러가 발생합니다.
PHP의 변수이름은 알파뉴머릭과 밑줄로만 이루어져 있습니다. 만약 쿠키명에 유효하지 않은 문자들이 포함되어 있다면 유효하지 낳은 문자들은 밑줄(_)로 변환됩니다. 예를 들어, 쿠키명 "in%va.lid_"는 "in_va_lid_"로 변환됩니다.
$HTTP_COOKIE_VARS[]를 사용하여야 할 이유는?
$HTTP_COOKIE_VARS["username"] 대신에 전역변수 $username를 사용하여도 동작결과는 동일합니다. 그러면 언제 $HTTP_COOKIE_VARS[]을 사용하여야 할까요? 이전페이지에서 세션값, GET, POST, 쿠키로 넘어 오는 모든 값은 전역변수로 넘어올 수도 있고 $HTTP_SESSION_VARS[], $HTTP_GET_VARS[], $HTTP_POST_VARS[], $HTTP_COOKIE_VARS[]와 같은 전역 배열 변수로도 넘어오지요. 여기서 보았듯이 배열로 넘어오는 값들은 각 요소(세션, GET, POST, 쿠키)마다 서로 다른 배열변수에 담겨오기 때문에 배열변수가 무엇이냐에 따라 넘어온 값이 어떠한 성격을 가지고 있는지 파악할 수 있습니다. 그러나 전역변수로 넘어온 값은 전역변수명만을 가지고는 그 값이 세션값이었는지, HTTP GET 방식으로 넘어왔는지, HTTP POST 방식으로 넘어왔는지, 쿠키값이었는지가 구분이 되지 않습니다. 사용상의 편이성만으로만 보면 전역변수를 사용하는 것이 좋겠지요. 그러나 보안이라는 측면에서 보면 넘어온 값의 성격을 구분하지 못할 때는 문제가 발생할 수 있습니다. 예를 들어 앞장(home.php)에서 아래와 같이 HTTP POST 방식으로 userid와 passwd값을 입력받아 서브밋하였습니다.
[code php;gutter:false] <FORM name=getID method="post" action="login_process.php">
<P>사용자ID : <INPUT type="text" name="login_userid" size="15"></P>
<P>비밀번호 : <INPUT type="password" name="login_passwd" size="15"></P>
</FORM> [/code]
이 값을 다음 장(login_process.php)에서 받았을 때 $HTTP_POST_VARS[] 배열을 사용하지 않고 전역변수 $login_userid, $login_passwd를 직접 사용한다면 이 값이 꼭 앞장 양식에서 입력되어 들어온다는 보장이 없습니다. 누군가가 부당한 목적을 위해 앞장을 통하지 않고 아래와 같이 URL 파라미터로 값을 입력할 수도 있지요.
login_process.php?login_userid=user3&login_passwd=test
위와 같이 URL 파라미터로 login_process.php 페이지로 $login_userid, $login_passwd 값을 전달할 수 있지요.
아래와 같은 세션값도 마찬가지입니다. $access_userid 값과 $access_userid 값은 login_process.php 페이지에서 home.php 페이지로 세션을 통해 비밀스럽게(?) 전달되어 인증처리를 하여야 하는데 역시 누군가가 부당한 목적을 위해 세션을 통하지 않고 URL 파라미터를 통해 $access_userid 값과 $access_userid 값을 home.php 페이지로 전달할 수 있지요.
이것을 방지하기 위해 각 요소(세션, GET, POST, 쿠키)마다 배당된 다른 배열변수를 이용해 전역변수를 덮어쓰기하는 것입니다.
보안상 신경쓰지 않아도 되는 전역변수 값이야 이렇게 할 필요가 없으나 인증에 필요한 값들은 불편하더라도 이같은 코딩 습관에 익숙하시는 것이 바람직합니다.
공개 소스 중에는 이렇게까지 하지 않는 경우도 많이 있으나 여러분이 이러한 면에도 관심을 가져주었으면 해서 때에 따라서는 불필요할 지도 모르지만 코드를 일부로 포함시켰습니다.
쿠키 삭제하기
쿠키는 보통 setcookie() 함수의 첫번째 매개변수만으로 삭제할 수 있습니다.
[code php;gutter:false] setcookie("mycookie"); [/code]
그러나 때에 따라서는 첫번째 매개변수만 지정할 경우 해당 쿠키가 삭제되지 않는 경우를 볼 수 있습니다. 이것은 쿠키를 설정할 때 유효도메인, 유효경로를 지정한 경우가 대부분입니다. 이와 같은 경우에는 쿠키 설정할 때 지정된 유효도메인과 유효경로를 삭제시에도 지정하여야 합니다.
[code php;gutter:false] setcookie("mycookie", "cookie_value", 0, "/exam", ".phpclass.com"); [/code]
예를 들어 쿠키 설정할 때 위와 같이 지정하였다면, 쿠키 삭제할때는 아래와 같이 지정하여야 합니다. 삭제할 때 유효기간 설정값은 예를 들은 것 뿐이며 적절한 과거 시점을 지정하면 됩니다.
[code php;gutter:false] setcookie("mycookie", "", time()-31536001, "/exam", ".phpclass.com"); [/code]
현재 설정된 쿠키 변수들에는 영향을 미치지 않으며, 또한 $HTTP_COOKIE_VARS[]도 변경시키지 않는다.

 

쿠키의 생성, 참조, 삭제되는 시점
setcookie() 함수로 쿠키를 생성하거나 삭제하더라도 새로운 HTTP 요구(require)가 없으면 이 쿠키에 대한 정보가 쿠키용 전역변수 또는 전역배열변수 $HTTP_COOKIE_VARS[]에 적용되지 않습니다. 이러한 setcookie() 함수의 동작원리를 잘 이해하고 있어야 합니다. 따라서 위에서와 같이 setcookie("mycookie")를 통해 쿠키를 삭제하더라도 현재 설정된 쿠키 전역변수와 전역배열변수 $HTTP_COOKIE_VARS[]의 내용은 계속 유지됩니다. setcookie() 함수를 통해 쿠키를 생성하면 이 값은 로컬시스템(사용자 하드드라이브)에 저장되었다가 다음 페이지를 읽을 때 쿠키정보를 서버로 보내게 됩니다. 서버는 이 쿠키정보를 이용하여 전역변수값으로 설정해 주지요.
setcookie() 함수 사용시 발생하는 에러
setcookie() 함수를 사용하는 데 주의 할 점이 있습니다. setcookie() 함수는 일반적인 HTML 태그 또는 PHP로부터 보내지는 실제의 출력 이전에 호출되어야 합니다. setcookie() 함수를 호출하기 전에 include() 또는 auto_prepend를 통하여 코드를 읽어들일 수 있는데 이러한 코드에 브라우저로 출력되는 스페이스 또는 빈줄이 있으면 에러가 발생합니다. 이 에러에 대한 것은 제 홈페이지의 Q&A 게시판에서 언급되어 있으며, 메뉴 "후키라이브러리 >> 캐시리미터 >> 헤더 관련 PHP 함수" 의 header() 함수에서도 언급되어 있으니 참조바랍니다. 아래는 이 때 PHP3 및 PHP4에서 발생하는 에러메시지입니다.
PHP3일 때
=========
Warning: Oops, php3_SetCookie called after header has been sent
in /home/....../test.php3 on line ???

PHP4일 때
=========
Warning: Cannot add header information - headers already sent by
(output started at /home/....../test.php:3)
in /home/....../test.php on line ???
setcookie() 함수 호출 순서
PHP3에서의 실험
PHP는 쿠키들을 PHP 스크립트에 있는 setcookie() 호출들의 순서와 역순으로 서버로 전달합니다. 앞에서 배열요소를 쿠키에 저장할 때도 확인하였습니다. 어떻게 해서 이런 현상이 발생하였을까요? 이를 확인하기 위해 다시 소스코드를 분석해 보겠습니다. 아래는 PHP3.0.14 소스파일 head.c에 있는 아파치 웹서버에 대한 php3_header() 함수 및 _php3_SetCookie() 함수를 요약한 것입니다. head.c 파일은 PHP3.0.14 소스파일의 압축을 풀면 php-3.0.14\functions\head.c에 있습니다.
[code c;gutter:false] void _php3_SetCookie(char * name, char * value, time_t expires
, char * path, char * domain, int secure)
{
......(중간생략)......

if (name) name = estrdup(name);
if (value) value = estrdup(value);
if (path) path = estrdup(path);
if (domain) domain = estrdup(domain);
php3_PushCookieList(name, value, expires, path, domain, secure);
} [/code]
SetCookie() 함수는 내부적으로 결국 _php3_SetCookie() 함수를 실행하게 되어있는데 이 함수가 하는 일이라고는 단지 쿠키 설정 정보들을 CookieList라는 스택 자료 구조에 저장(Push)하는 것 뿐입니다.
[code c;gutter:false] PHPAPI int php3_header(void)
{

......(중간생략)......

cookie = php3_PopCookieList(); //<-- 스택으로부터 데이터를 가져음
while (cookie) {

......(중간생략)......

cookie = php3_PopCookieList(); //<-- 스택으로부터 데이터를 가져옴
efree(tempstr);
}
......(중간생략)......

send_http_header(GLOBAL(php3_rqst)); //<-- 응답헤더 전송

......(중간생략)......

return(1);
} [/code]
응답헤더를 통해 보낼 정보(쿠키정보 포함)가 다 모아지면 php3_header() 함수를 실행하게 됩니다. 이 함수를 살펴보면 위에서와 같이 SetCookie() 함수를 통해 스택 CookieList에 모아진 자료를 하나씩 차례로 불러와 헤더 정보에 추가하는 것을 알 수 있습니다.
자료구조론을 읽어보신 분은 이미 이해하셨겠지만 CookieList가 스택구조다 보니 저장(Push)될 때와 반대의 순서로 읽어(Pop) 들인다는 것(후입선출구조)입니다. 그러니 응답헤더에 포함되는 순서가 SetCookie() 함수 실행순서와 뒤바뀌게 되고 결국 쿠키가 구워지는 순서가 뒤바뀌게 되는 것이지요.
제가 공개하는 쿠커(Cooker)와 같이 때에 따라서는 이 순서가 바뀌면 안돼는 웹애플리케이션도 필요할 것입니다. 이러한 경우는 어떻게 해야 할까요. 해결방법은 두가지, 자바스크립트를 이용하던가 아니면 header() 함수를 이용하시면 됩니다. 쿠커에서는 이 문제때문에 setcookie() 함수 대신에 header() 함수를 이용하였습니다.
setcookier() 호출 순서와 역순으로 브라우저에서 쿠키가 생성되거나 삭제되기 때문에 만약 동일한 이름을 가진 쿠키를 삭제하고 새롭게 다른 값으로 설정하기를 원한다면 setcookie()로 새로운 쿠키를 먼저 설정한 다음, 나중에 다시 setcookie()를 호출하여 예전의 쿠키를 삭제해야 합니다.
[code php;gutter:false] <?php
// 새로운 쿠키를 설정
setcookie("mycookie", "cookie_value");
// 예전의 쿠키를 삭제
setcookie("mycookie");
?> [/code]
PHP4에서의 실험
실험까지는 하지 않았고 PHP4 메뉴얼에 의하면 setcookie() 함수 호출 순서와 서버로 전달되는 순서가 같게 변경되었습니다. 제 개인 생각으로도 PHP4에서의 방법이 옳지 않나 생각합니다. 뒤에서 언급된 쿠키정보클래스 "쿠커(Cooker)에서도 이 호출순서와 서버로 전달되는 순서가 역순이라 setcookie() 함수를 사용할 수가 없었습니다. 그래서 setcookie() 함수 대신에 header() 함수를 직접 이용하게 되었지요. 쿠커를 작성할 때 PHP4에서는 setcookie() 함수를 사용해도 되겠지만 PHP3와의 호환성을 위해 setcookie() 함수를 사용하지 않았습니다.

'phpsource > 캐시&세션&쿠키' 카테고리의 다른 글

{쿠커}9.쿠커  (0) 2001.02.20
{쿠커}8.document.cookie 객체  (0) 2001.02.20
{쿠커}6.쿠키 다루기  (0) 2001.02.20
{쿠커}5.쿠키 규격  (0) 2001.02.20
{쿠커}4.브라우저 설정  (0) 2001.02.20
Posted by 방글24
쿠키 생성 및 접근
쿠키를 생성하기 위해서는 웹 서버가 앞장에서 다룬 쿠키 규격에 맞게 "Set-Cookie" HTTP 헤더 정보를 보내면 됩니다. 즉 HTTP 헤더를 생성하는 CGI를 작성하면 원하는 내용을 쿠키에 입력하는 것이 가능합니다. 클라이언트에 저장된 쿠키를 꺼내기 위해서는 클라이언트가 정보요청을 할 때(즉 CGI을 불렀을 때) 함께 넘어오는 환경변수 HTTP-COOKIE에 저장되어 있는 정보를 추출하여 사용하면 됩니다. PHP 또는 자바스크립트에서는 이러한 작업을 아주 쉽게 할 수 있는 방법을 제시합니다. 물론 C언어와 같은 다른 수단을 사용하더라도 쿠키 규격을 만족하도록 HTTP 헤더 또는 환경변수를 다루면 되지만 PHP 또는 자바스크립트보다는 좀 다루기가 쉽지 않을 것입니다.
여기서는 PHP와 자바스크립트를 이용하여 쿠키를 다루는 방법에 대하여 기술할 것입니다. 자세한 것은 다음 장 "setcookie() 함수" 및 "document.cookie 객체"를 참조바랍니다.
PHP
쿠키를 생성하기 위한 함수로 SetCookie() 함수를 제공하며, 클라이언트에서 전달된 쿠키는 쿠키명에 해당하는 전역변수를 가지고 다루거나 아니면 $HTTP_COOKIE_VARS[]라는 전역배열변수를 가지고 다룰 수 있습니다.
[code php;gutter:false] <?php

if (!isset($mycookie)) {
setcookie("mycookie", "cookie_value", time+3600);
die("<META http-equiv='Refresh' content='0; URL=$PHP_SELF'>");
} else {
echo "$mycookie<BR>\n";
}

?> [/code]
자바스크립트
document.cookie 객체는 쿠키의 모든 이름과 값을 가지고 있고, 자바스크립트에서 이 속성(property)을 이용할 수 있습니다. 사용자들은 아래와 같이 document.cookie를 마치 문자열 변수처럼 취급하여 쉽게 쿠키의 정보를 제어할 수 있습니다.
[code javascript;gutter:false] document.cookie = "ID=" + escape("123456789")
+ "; expires=Thu, 01-Jan-70 00:00:01 GMT"
+ "; path=/exam"
+ "; doamin=.phpclass.com"
+ "; secure"; [/code]

'phpsource > 캐시&세션&쿠키' 카테고리의 다른 글

{쿠커}8.document.cookie 객체  (0) 2001.02.20
{쿠커}7.setcookie() 함수  (0) 2001.02.20
{쿠커}5.쿠키 규격  (0) 2001.02.20
{쿠커}4.브라우저 설정  (0) 2001.02.20
{쿠커}3.보안  (0) 2001.02.20
Posted by 방글24
쿠키 규격에 관련된 자료
아래에는 쿠키 규격(HTTP Cookies Specification)에 관련된 문서를 링크시켜 놓았습니다.
  • 넷스케이프의 쿠키에 관한 예비 규격서(www.netscape.com/newsref/std/cookie_spec.html)
    (수정:2010.1.11) 오래된 문서라서 현재는 링크가 깨진 상태입니다. 복사본을 참조하세요.
  • RFC2109 : Proposed Standard "HTTP State Management Mechanism"(www.cis.ohio-state.edu/htbin/rfc/rfc2109.html)
    IETF(Internet Engineering Task Force)의 HTTP Working Group에서 쿠키의 표준화 작업을 하고 있으며 현재의 쿠키는 RFC 2109를 따르고 있습니다.
    (수정:2010.1.11) 오래된 문서라서 현재는 링크가 깨진 상태입니다. 복사본을 참조하세요.
쿠키의 설정
위 규격에 의해 HTTP 서버에서는 다음과 같은 구조의 Set-Cookie 헤더를 통해 쿠키를 클라이언트로 전달합니다.
Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
대문자는 사용자가 특정값을 입력하는 부분이고 소문자는 예약어로서 반드시 그대로 써야만 합니다.
쿠키 헤더 문법에는 쿠키내용, 유효기간, 유효경로, 유효도메인, 보안설정의 다섯가지의 구성요소를 가집니다. 여기에서 여기서 쿠키명과 쿠키값으로 이루어지는 실질적인 쿠키내용을 제외한 다른 구성요소는 모두 쿠키의 유효 여부를 판단하는데 사용됩니다. 즉 각 구성요소에 입력된 값과 모두 일치하는 서버만이 그 쿠키를 참조할 수 있는 것입니다.
구성요소 문법 필수/선택 예제
쿠키내용 NAME=VALUE 필수 ID=123456789
유효기간 expires=DATE 선택 expires=Tuesday, 06-Feb-01 13:57:21 GMT
유효경로 path=PATH 선택 path=/exam
유효도메인 domain=DOMAIN_NAME 선택 domain=.phpclass.com
보안설정 secure 선택 secure
쿠키내용 NAME=VALUE
실제 쿠키의 내용을 입력하는 곳으로 저장될 쿠키명과 쿠키값을 설정합니다. 쿠키내용은 Set-Cookie 헤더에서 반드시 설정하여야 하는 필수적인 필드입니다. 쿠키명이나 쿠키값의 문자열 중에는 세미콜론(;),콜론(,) 또는 공백값이 들어갈 수 없습니다. 이러한 특수문자들을 표현하기 위해서는 URL 인코딩 방식에 따라 %3B와 같은 형태로 기술해주면 된다.
URL 인코딩/디코딩함수 자바스크립트 PHP
인코딩 escape() urlencode()
디코딩 unescape() urldecode()
유효기간 expires=DATE
쿠키의 유효기간을 설정하는 항목으로 유효기간이 지난 쿠키는 자동으로 지워집니다. 생략이 가능하며 특별히 명시하지 않았을 경우 브라우저 세션이 종료되는 순간 쿠키값이 자동으로 사라집니다. 날짜의 형식은 "Wdy, DD-Mon-YYYY HH:MM:SS GMT"과 같으며 여기서 Wdy란 요일, DD-Mon-YYYY는 일-월-년, HH:MM:SS는 시:분:초, GMT는 그리니치 표준시를 나타냅니다.
Sun, 01-Jan-1995 01:00:00 GMT
유효경로 path=PATH
경로 정보는 쿠키의 유효한 경로를 설정하는 항목입니다. 유효경로는 현재 디렉토리의 하위디렉토리를 모두 포함합니다. /exam 라고 설정하면 /exam 뿐만 아니라 /exam/cookie에서도 유효합니다. 또한 경로명의 부분 문자열로 지정할 수 있습니다. 즉 /exam의 경로로 설정된 쿠키는 /exam뿐만 아니라 /example에서도 유효하다. 만약 부분문자열이 아닌 문자열 전부가 일치한 디렉토리만 유효하도록 하려면 /exam/ 와 같이 뒤에 "/"를 지정합니다. 유효경로를 생략하면 쿠키를 지정하는 HTTP 응답 헤더와 같이 넘어오는 문서의 경로로 지정됩니다. 유효경로를 /라고 지정하면 쿠키를 서버의 모든 페이지에서 사용할 수 있습니다.
유효도메인 domain=DOMAIN_NAME
도메인 정보는 쿠키가 유효한 서버를 지정할 때 사용됩니다. 즉 여기서 지정된 도메인 이외의 서버에서는 이 쿠키의 값을 참조할 수 없습니다. 유효도메인을 지정하지 않으면 쿠키에 값을 입력한 서버의 호스트 이름이 지정됩니다.
복수 도메인에서 쿠키를 사용하기 위해서는 호스트명 앞쪽을 생략할 수 있습니다. 예를 들어 쿠키를 www.phpclass.com과 hwooky.phpclass.com 모두에서 사용하려면 .phpclass.com으로 유효도메인을 설정합니다.
보안정보 secure
쿠키의 마지막에 secure 설정이 지정되면 실제로 쿠키의 정보가 암호화되어 저장됩니다. 그러나 호스트가 SSL(Secure Sockets Layer)을 지원할 때(예를 들어 HTTPS 서버)만 유효하며(쿠키를 전송하며) 그 이외는 무시됩니다. 이것은 서버와 브라우저가 모두 보안을 지원한다는 것을 의미합니다. 만일 secure 인수가 없다면 쿠키가 네트워크 상에서 암호화되지 않은 채로 전송될 수 있다는 것을 의미합니다.
쿠키의 요청
쿠키가 설정된 이후에는 클라이언트가 서버에 문서를 요청할 때, 쿠키가 유효한지 검사하기 위해서 쿠키 리스트를 검사하는데 이 때 우선 유효도메인 검사하게 됩니다. 이 때 유효도메인과 서버의 도메인이 일치하는가를 뒤에서 부터 검사하는 방법(tail matching)을 이용합니다. 즉 유효도메인이 .phpclass.com라고 지정되어 있으면 이 쿠키는 www.phpclass.com, hwooky.phpclass.com abc.mingky.phpclass.com 등의 도메인과 일치하는 것으로 처리되지만 www.phpschool.com과 같은 경우는 불일치로 처리됩니다.
일단 도메인 정보의 확인 작업이 통과된 후 쿠키가 유효한 경로를 한번 더 확인하게 됩니다. 이러한 쿠키의 유효성을 통과한 쿠키는 다음과 같은 HTTP 요구헤더를 통해 웹서버로 쿠키에 대한 정보를 넘겨주게 됩니다.
Cookie: ID=12345678; PW=abcdefghi
쿠키의 동작
쿠키의 설정과 요청이 실제로 어떠한 절차로 이루어지는지 살펴보면 아래와 같습니다.
① 클라이언트가 서버측의 문서를 요청하면 다음과 같은 응답 헤더를 통해 쿠키가 설정됩니다.
Set-Cookie: ID=123456789; path=/exam; expires=Tuesday, 06-Feb-01 13:57:21 GMT
② 브라우저가 '/exam' 경로에 있는 웹문서를 요청할 때 서버로 요구 헤더를 통해 다음과 같은 쿠키 정보가 전달됩니다.
Cookie: ID=123456789
③ CGI 프로그램에서는 HTTP_COOKIE CGI 환경변수를 통해 쿠키명(ID)과 쿠키값(123456789)을 읽어 처리합니다.
쿠키의 제한사항
각 클라이언트는 여러 개의 쿠키를 가질 수 있습니다. 따라서 여러 서버에 접속하여도 각 서버에 해당하는 쿠키를 각각 따로 관리할 수 있습니다. 그러나 쿠키들의 남용을 방지하기 위해 웹브라우저가 관리하는 쿠키의 크기는 제한됩니다.
▶ 최대 300개의 쿠키 저장
▶ 하나의 쿠키는 공백을 포함하여 name/value의 합이 4KB로 제한
▶ 서버/도메인별로 최대 20개의 쿠키 저장
쿠키의 최대 저장 개수를 초과하면 이전에 저장된 쿠키는 새로운 쿠키가 덮어 쓰게 되며 , 이때 LRU(Least Recently Used), 방식에 따라 최근에 가장 적게 사용된 쿠키가 차례로 지워지게 됩니다.
쿠키를 유효기간 전에 파기시키려면 expires 속성을 지나간 시간으로 하여 재지정 해주면 됩니다. 이때는 쿠키명과 유효경로 등이 지우려는 쿠키의 정보와 일치해야 합니다.
Set-cookie 하나당 하나의 쿠키만 보낼 수 있습니다.

'phpsource > 캐시&세션&쿠키' 카테고리의 다른 글

{쿠커}7.setcookie() 함수  (0) 2001.02.20
{쿠커}6.쿠키 다루기  (0) 2001.02.20
{쿠커}4.브라우저 설정  (0) 2001.02.20
{쿠커}3.보안  (0) 2001.02.20
{쿠커}2.웹페이지 상태유지  (0) 2001.02.20
Posted by 방글24
쿠키 허용 여부 설정
넷스케이프 3.x와 인터넷 익스플로러 3.x에서는 쿠키 사용이 기본적으로 가능하기 때문에 따로 설정해 줄 필요가 없으나, 넷스케이프 4.x, 또는 인터넷 익스플로러 4.x 이상의 버전에서는 별도의 쿠키 설정이 필요합니다.
쿠키 사용을 원하지 않을 경우에는 웹브라우저의 설정항목에서 "사용 안함"을 선택하시면 됩니다. 그러면 쿠키는 전혀 전송되지 않을 것이며, 새로운 쿠키도 받아들여지지 않을 것입니다. "모든 쿠키받음" 또는 "사용"을 선택하면 서버로부터 오는 쿠키가 받아들여지고 저장된 쿠키가 전송될 것입니다. 때에 따라서는 쿠키가 제공될 때마다 경고 표시하도록 설정할 수 있습니다. 이 기능을 사용하면 쿠키를 사용하는 웹사이트를 접속할 때마다 쿠키 허용 여부를 묻는 경고 메시지가 나타나기 때문에 웹서핑하기AC가 불편할 것입니다. 많은 홈페이지가 쿠키를 사용하고 있기 때문에 웹서핑을 쾌적하게 즐기시려면 쿠키의 사용을 가능하게 해 주어야 합니다.
넷스케이프 네비게이터 4.0
작업 표시줄에서
1. 편집을 클릭한 다음
2. 환경설정을 선택합니다.
3. 고급을 클릭합니다.
4. "쿠키"란에서 옵션을 설정합니다.
< 넷스 4.0에서의 쿠키 설정 화면 >
인터넷 익스플로러 4.0
1. 보기 메뉴에서
2. 인터넷 옵션을 선택합니다.
3. 고급 탭을 클릭합니다.
4. 시스템 보안 아래의 노란색 느낌표 아이콘까지 아래로 스크롤하여
쿠키 사용 여부를 조정하는 세 가지 옵션 중 하나를 선택합니다.
인터넷 익스플로러 5.0
1. 도구 메뉴에서
2. 인터넷 옵션을 선택합니다.
3. 보안 탭을 클릭합니다.
4. 인터넷을 클릭한 다음 사용자 정의 단추를 누릅니다.
5. 쿠키까지 아래로 스크롤하여 옵션을 설정합니다.
< 익스 5.0에서의 쿠키 설정 화면 >
쿠키 파일
쿠키는 4K바이트 이하의 파일로서, 쿠키명과 값, 방문한 웹사이트의 이름 등의 정보가 담겨 있습니다. 쿠키가 저장되는 위치는 사용하고 있는 브라우저와 운영체제에 따라 다릅니다.
넷스케이프 네비게이터 4.0
넷스케이프는 모든 쿠키를 하나의 파일로 묶어 저장하며 윈도우 환경에서는 이와 같이 쿠키를 가지고 있는 파일을 "C:\Programs Files\Netscape\Users\<사용자명>\cookies.txt"에서 찾을 수 있습니다. 이와 같이 넷스케이프는 사용자별로 쿠키를 저장합니다. 로컬시스템의 사용자 설정에서 복수사용자 설정을 하지 않았다면 "C:\Programs Files\Netscape\Users\Default\cookies.txt"에서 쿠키 파일을 찾을 수 있습니다. 예를 들어 아래와 같은 쿠키 정보가 있다고 하죠.
# Netscape HTTP Cookie File
# http://www.netscape.com/newsref/std/cookie_spec.html
# This is a generated file! Do not edit.

.phpclass.com TRUE /exam2 FALSE 981449338 ID 5
쿠키 파일에 담겨지는 정보는 쿠키를 제공한 웹사이트의 이름, 쿠키의 유효기간, 쿠키명, 그리고 쿠키값 등이 있습니다. 위의 첫 칸은 쿠키를 제공한 URL 주소를 담고 있습니다. 위와 같은 경우 각 칸의 의미를 살펴보면 다음과 같습니다. 유효기간은 1970년을 기점으로 잡아 소멸되는 시점까지를 초단위로 나타냅니다.
.phpclass.com <- 도메인 설정
TRUE <- 도메인을 지정함(???)
/exam2 <- 경로 설정
FALSE <- 보안 설정
981449338 <- 유효기간 설정
ID <- 쿠키명
5 <- 쿠키값
인터넷 익스플로러 5.0
윈도우 환경에서 익스플로러를 실행하는 경우에는 쿠키들이 C:\Windows\Cookies 폴더에 여러 파일로 나뉘어서 저장됩니다. 그러나 이 파일들은 C:\Windows\Temporary Internet Files 폴더에 있는 쿠키의 복사본입니다. 익스플로러는 쿠키 하나를 하나의 텍스트 파일에 담고 있습니다. 이러한 쿠키 파일을 관리할 수 있는 index.dat라는 파일이 별개로 존재합니다.
예를 들면 C:\Windoes\Cookies 디렉토리를 보면 아래와 같은 쿠키파일들이 있습니다.
C:\Windows\Cookies\hwooky@ad.shinbiro[2].txt
C:\Windows\Cookies\hwooky@adsquare.co[2].txt
C:\Windows\Cookies\hwooky@flycast[1].txt
C:\Windows\Cookies\hwooky@google[1].txt
C:\Windows\Cookies\hwooky@cookie[1].txt
쿠키 파일의 내용을 보면 아래와 같습니다. 첫번째줄과 두번째줄이 각각 쿠키명과 쿠키값을 의미합니다. 나머지는 여러분이 분석해 보세요. 저도 잘 모름.
ID <- 쿠키명
6 <- 쿠키값
www.phpclass.com/example/cookie/
0
3375109376
29397019
118715040
29397010
*
받은 쿠키 보기
넷스케이프 네비게이터 4.0
넷스에서는 쿠키를 볼 수 있는 기능을 별도로 제공하고 있지 않습니다. 따라서 그 내용을 보기 위해서는 직접 쿠키 파일을 텍스트 편집기에서 보면 됩니다. 이러한 쿠키 파일은 보통 "C:\Programs Files\Netscape\Users\Default\cookies.txt"에 있습니다.
인터넷 익스플로러 4.0, 5.0
익스는 브라우저에서 받은 쿠키 파일 리스트를 확인할 수 있습니다. 그러나 파일 리스트만 볼 수 있지 그 내용을 확인할 수는 없습니다. 내용을 보기 위해서는 넷스에서와 같이 텍스트 편집기를 이용하여야 합니다.
***익스 4.0***

작업 표시줄에서
1. 보기를 클릭한 다음
2. 인터넷 옵션을 선택합니다.
3. 일반 탭(기본 탭)에서
4. 설정을 클릭한 다음
5. 파일 보기를 선택합니다.
***익스 5.0***

작업 표시줄에서
1. 도구를 클릭한 다음
2. 인터넷 옵션을 선택합니다.
3. 일반 탭(기본 탭)에서
4. 설정을 클릭한 다음
5. 파일 보기를 선택합니다.
쿠키파일 지우기
넷스에서 쿠키 파일을 지우려면 사용자가 직접 "C:\Programs Files\Netscape\Users\<사용자명>" 폴더 안에 있는 cookies.txt 파일을 찾아서 파일 자체를 지우거나 편집을 해야 합니다.
익스에서 쿠키 파일을 지우려고 할 때, C:\Windows\Cookies 폴더에 있는 쿠키 파일을 지워서는 소용없고 C:\Windows\Temporary Internet Files 폴더에 있는 원본을 직접 지워야 합니다. 지울 때는 현재 동작하고 있는 브라우저를 종료한 다음에 작업하시는 것이 좋습니다. 현 브라우저가 쿠키를 임시 저장하고 있어서 이 정보가 쿠키 파일을 지운 후에 새롭게 쿠키 파일에 저장될 수 있습니다.

'phpsource > 캐시&세션&쿠키' 카테고리의 다른 글

{쿠커}6.쿠키 다루기  (0) 2001.02.20
{쿠커}5.쿠키 규격  (0) 2001.02.20
{쿠커}3.보안  (0) 2001.02.20
{쿠커}2.웹페이지 상태유지  (0) 2001.02.20
{쿠커}1.쿠키란?  (0) 2001.02.20
Posted by 방글24
쿠키 보안성
쿠키는 쿠키를 생성한 서버 또는 쿠키를 받도록 허용된 서버로만 전송됩니다. 이를 위해 서버가 쿠키를 설정할 때에는 그 쿠키가 전송되는 서버의 범위를 제한하게 됩니다.
그러나 쿠키는 각 페이지간 상태 유지를 위해 설계된 것이지 사용자 인증과 같은 애플리케이션을 위해 설계된 것이 아니기 때문에 회원인증 정보 또는 주민등록번호, 카드번호와 같은 사용자 정보를 쿠키에 저장하는 것은 매우 위험한 것 같습니다. 쿠키 파일은 로컬시스템을 사용하는 누구나 접근할 수 있습니다. 파일에 저장되지 않은 상태에서도 원서버(original server)을 가장한 스푸핑 서버(spoofing server)에 의해 쿠키의 내용이 수정될 수도 있다고 합니다. 아래에는 쿠키 보안에 관련된 문서를 링크시켜 놓았으니 쿠키를 이용하기 전에 충분히 살펴보시기 바랍니다.
쿠키 보안에 관련된 자료
  • 쿠키와 프라이버시
    목차 : 프롤로그/여러분의 쿠키는 안녕하신가?/쿠키는 왜 만들었나?/쿠키는 믿을만한가?/해결방법은 없나?
  • Cookie sniffing
    목차 : 개요/현황/취약점 발생원인/해킹 기법/모의 실험/보안 권고
  • 국내 인터넷 서비스 제공업체 보안 취약성 분석 보고서
    목차 : 개요/현황/웹 인증 방식 소개/모의 구축 모델/사례연구(취약점 분석)/실제 모의 사례/보안 권고/취약점 분석(CASE TEST)/결론/관련자료
  • 악성코드에 의한 HTTP Cookie 유출 문제점 및 대책
    목차 : 설명/해결책
  • 쿠키 및 세션을 이용한 인증의 보안 취약성 경고
    목차 : 들어가기에 앞서/PHP에서 쿠키를 이용한 인증의 위험 (PHP에서 GET 방식을 이용한 쿠키 스푸핑)/헤더 조작을 통한 cookie spoofing/쿠키 변수 이름 알아내기/쿠키 인증에 대한 다른 아이디어들/Cookie 인증의 대안, Session/Session spoofing/Session sniffing/Session의 한계를 넘어/글을 마치며
(수정:2010.1.11) 관련정보에 대한 홈페이지 링크가 너무 오래되어 연결되지 않아 삭제합니다.
쿠키 보안 대책
위에서 링크한 자료들을 종합하여 보면 웹사이트 개발자나 사용자가 쿠키를 사용할 때는 아래와 같은 점에 유념하시는 것이 바람직할 것 같습니다. 위에 링크된 자료를 살펴보면 "쿠키 기반의 회원 인증 시스템"을 모델링해 놓은 예제가 있으니 이 부분도 꼭 살펴보시기 바랍니다.
쿠키인증 기법을 사용하는 사이트의 보안대책
① http://www.netscape.com/newsref/std/cookie_spec.html 사이트의 쿠키 스팩을 따릅니다. 특히, 쿠키 저장시 타인이 임의로 쿠키를 읽어들일 수 없도록 도메인과 경로 지정에 유의합니다. 쿠키들은 쿠키를 받도록 허용된 서버로만 전송됩니다. 서버가 쿠키를 설정할 때 도메인을 지정하면 그 쿠키가 전송되는 서버의 범위를 제한할 수 있습니다. 경로 설정값을 이용하면 쿠키가 전송되는 서버를 제한할 수 있을 뿐만아니라 서버 내의 경로를 제한할 수도 있습니다. 쿠키의 경로를 지정하면 지정된 경로 및 그 하위 경로에 있는 웹문서로만 쿠키가 전달됩니다. 쿠키의 경로를 "/"로 지정하면 해당 서버의 모든 경로에 대하여 쿠키를 전달하기 때문에 가능하면 "/"를 지정하지 말고 특정 디렉토리를 지정하여 사용하기 바랍니다.
② 쿠키에 들어가는 정보는 가능하면 암호화하여 저장합니다. 만약 패스워드 부분을 사용하게 된다면 반드시 암호화하여 저장합니다.
③ 가능하면 쿠키에 지정하는 값을 최소화합니다. 쿠키 정보만 가지고도 개인 정보를 알 수 있는 부분은 피합니다.
④ 개인 정보 열람 및 수정 페이지는 패스워드나 유일한 사용자의 정보를 재입력해야만 들어갈 수 있게 구축합니다. 만약 도용을 당하더라도 개인 패스워드 등 사용자 정보를 입력하게 함으로써 개인의 정보 열람 및 수정을 불가능하게 합니다.
⑤ 도메인과 경로지정에 따라 차이가 있을 수 있으나 대부분 쿠키 정보는 그것을 제공한 사이트에서만 검색할 수 있으므로 검증되지 않은 사용자용 홈페이지는 인증서버와 다른 도메인에 위치시킴으로써 쿠키정보의 유출을 막을 수 있습니다. 즉, 홈페이지 보안을 위해 사용자용 홈페이지는 별도의 도메인으로 서비스합니다.
⑥ 웹메일 보안을 위해 수신된 웹메일의 본문에 첨부되는 HTML 가능 자료의 스크립트 검사를 하거나, 첨부되는 자료는 다른 도메인 사용을 권장합니다.
⑦ 게시판 제목, 본문에는 스크립트 언어의 사용을 금지시키도록 합니다.
⑧ 일반 사용자가 업로드할 수 있는 컨텐츠 부분에는 쿠키 사용을 억제합니다.
⑨ 개인 정보 열람이 가능한 도메인은 분리하거나 인증 서버를 달리합니다.
일반 사용자들의 보안대책
쿠키를 전혀 사용하지 못하도록 브라우저를 설정하면 쿠키 보안을 걱정할 필요가 없겠지만 많은 웹사이트가 쿠키를 전제로 작성되어 있는 현실에서 이는 받아들이기 어려울 것입니다. 쿠키를 사용한다는 것을 전제로 보안 대책을 살펴보면 아래와 같습니다.
① 웹메일 서비스 옵션에서 '자바스크립트 허용여부' 등을 선택할 수 있다면 허용하지 않는 것으로 설정합니다.
② 로그인한 상태로 타인의 홈페이지를 방문하지 않습니다.
③ 쿠키를 받아들이기 전에 주의를 촉구하도록 세팅할 수 있습니다. 그러나 매번 쿠키를 받을 때마다 이에 응답한다는 것은 웹서핑하는데 많은 불편을 가져오게 될 것입니다.
④ 쿠키는 받아들이되 민감한 정보는 결코 입력하지 않습니다. 주민등록번호, 신용카드번호를 입력받는 페이지가 이러한 정보를 쿠키에 저장할 수도 있습니다. 그러니 이러한 정보는 어떠한 경우에도(?) 입력하지 않는 것이 좋겠지요.
대안으로서의 세션
쿠키를 이용한 인증은 어떠한 경우에도 완벽하지 않기 때문에 중요한 정보는 서버에 저장하고 쿠키와 서버의 정보를 비교하여 사용자 인증을 수행하는 것이 좋습니다. 그러나 이러한 방식으로 동작하는 세션의 경우도 주의를 기울이지 않으면 항상 문제가 될 수 있습니다. "쿠키 및 세션을 이용한 인증의 보안 취약성 경고" 문서를 참조바랍니다.
쿠키의 위험성
쿠키에 담긴 내용(신용카드번호와 같은)때문에 쿠키의 위험성을 논하는 것이지 단순한 텍스트 문서로 되어 있는 쿠키가 여러분의 로컬시스템에 바이러스를 심거나 하드디스크를 날려버리지도 않습니다. 단지 그 정보를 서버로 전송할 수 있을 뿐입니다.
PC방에서와 같이 여러사람이 같이 사용하는 로컬시스템에서는 이전 사람이 쿠키에 저장된 정보를 완벽하게 삭제하지 못하면 다음 사람이 이전 사람의 쿠키 정보를 볼 수도 있고, 앞사람과 동일 웹사이트를 접속할 때는 앞사람이 로그인한 상태에서 회원 페이지를 그대로(새로이 로그인 없이도) 볼 수 있으며, 사용자 정보를 브라우저에 그대로 보여 줄 수 있습니다.
쿠키 관리
쿠키는 웹을 좀 더 편리하게 사용할 수 있도록 해주기는 하지만 여러 사람이 같이 사용하는 로컬시스템이 경우에는 있을 지도 모르는 개인 정보를 담고 있는 쿠키를 적절히 관리하는 것은 중요할 것입니다. 쿠키 기반의 웹페이지를 서핑한 후에는 이러한 쿠키 파일을 직접 지울 수도 있고 아니면 쿠키를 관리해 주는 소프트웨어를 이용하여 지울 수도 있습니다.
직접 쿠키 파일을 지우는 방법
웹브라우저에서는 쿠키를 지울 수 있는 기능을 제공하지 않기 때문에 쿠키 파일을 직접 찾아 지워야 합니다. 자세한 것은 다음장 "브라우저 설정"을 참조바랍니다.
쿠키 관리 소프트웨어
직접 쿠키 파일을 지우는 방법은 불편합니다. 쿠키 관리 소프트웨어를 사용하면 저장된 쿠키를 읽고, 삭제하는 작업을 손쉽게 할 수 있으며 웹사이트에 따라 쿠키를 선택적으로 허용할 수 있습니다.
  • Complete Cleanup
    설명 : 하드디스크에 저장된 쿠키, 캐시 등을 지워주는 유틸리티입니다.
  • Cookie Cruncher
    설명 : 쿠키 크런처는 자신의 PC에 내장돼 있는 인터넷 쿠키를 모두 찾아주고, 텍스트 파일 형태로 내역을 볼 수 있고, 삭제할 수 있습니다.
  • Cookie Pal
    설명 : 쿠키 정보를 이용하는 웹사이트를 미리 지정해 접속과 함께 자동으로 쿠키를 차단하거나 읽어들이도록 하는 옵션 기능을 갖고 있습니다.
  • IEClean
    설명 : IE가 숨김파일(히든파일)로 지정해 놓고 있는 히스토리 폴더와 쿠키 폴더, 캐시 폴더의 파일들을 찾아서 보여 주며 삭제할 수 있습니다.
  • NSClean
    설명 : NS가 숨김파일(히든파일)로 지정해 놓고 있는 히스토리 폴더와 쿠키 폴더, 캐시 폴더의 파일들을 찾아서 보여 주며 삭제할 수 있습니다.
  • Cookie Crusher
    설명 : 웹 사이트에 따라 쿠키를 받아들이거나 거부하는 것을 도와주는 도구입니다.
  • Cache and Cookie Washer
    설명 : 쿠키 뿐만 아니라 캐시, 히스토리, Drop Down Address Bar, Auto Complete Data forms 등 인터넷을 사용하면서 생긴 모든 흔적을 찾아서 지워주는 도구입니다.
(수정:2010.1.11) 관련정보에 대한 홈페이지 링크가 너무 오래되어 연결되지 않아 삭제합니다.

'phpsource > 캐시&세션&쿠키' 카테고리의 다른 글

{쿠커}5.쿠키 규격  (0) 2001.02.20
{쿠커}4.브라우저 설정  (0) 2001.02.20
{쿠커}2.웹페이지 상태유지  (0) 2001.02.20
{쿠커}1.쿠키란?  (0) 2001.02.20
{세션핸들러}3.업그레이드 및 패치  (0) 2001.02.02
Posted by 방글24
상태 유지
메뉴 "회원인증에 대하여"의 세션관리에서도 언급하였듯이 인터넷의 기본 프로토콜인 HTTP(HyperText Transfer Protocol)를 사용하면, 웹 페이지에 대한 각각의 요구(request)은 다른 요구들과 상관 관계없이 모두 독립적입니다. 즉, 현재 페이지에 대한 데이터를 모두 수신하게 되면 웹서버는 현재 접속된 브라우저에 대하여 자동으로 세션이 종료합니다. 다음에는 웹브라우저에서 모든 것이 처리되기 때문에 웹서버와의 관계는 완전히 끊어지게 됩니다. 즉, 웹서버와 웹브라우저는 파일 단위의 요구, 연결, 송수신을 기본으로 하고 있습니다. 그렇기 때문에 웹서버는 그 방문자에게 이전에 어떠한 페이지가 보내어졌는지에 관한 아무런 기록도 가지고 있지 않습니다. 이런 프로토콜을 스테이트리스 프로토콜(stateless protocol)이라고 합니다.
그러나 대부분의 웹문서는 페이지간 변수의 값을 보존하여야 하는 경우가 많이 발생하게되어 상태 유지 관리가 필요하게 됩니다. 이러한 상태를 유지하기 위한 방법으로는 다음과 같은 것이 있습니다.
▷쿠키 사용
▷URL 링크에 암호화해서 넣기
▷히든 태그 사용
▷다른 프레임에 저장하기
▷웹서버에 저장하기
그전에는 이러한 상태 유지를 위해 URL 파라미터 또는 히든 태그(hidden type)를 이용하였으나 이러한 방법에 의한 상태 유지는 사용자가 연결을 유지하고 있는 동안의 단기간 지속할 뿐입니다. 연결이 끊어지게 되면 상태 유지가 종료하게 됩니다. 또한 각 페이지간에 정보를 넘겨주기 위해서 매 페이지마다 히든 태그(<INPUT type=hidden ......>)를 사용하게 되면 소스 구조가 대단히 지저분해지게 됩니다.
쿠키에 의한 상태유지
이러한 지속적인 상태 유지 문제(HTTP의 스테이트리스 문제)를 해결하고자 넷스케이프에서 쿠키라는 상태 정보 유지 시스템을 만들어 사용하던 것으로 지금은 익스플로러 또는 모자이크 등 대부분의 웹브라우저에서 널리 사용되고 있습니다. 쿠키를 이용하게 되면 서버와 브라우저가 지속적으로 정보를 주고 받을 수 있으며 이를 통해 어떤 상태를 지속적으로 유지할 수 있게 되는 것입니다.
상태를 유지한다는 말은 사용자가 같은 웹 사이트 내에서 서로 다른 페이지로 옮겨 다니는 상황에서 여러 정보들을 기억한다는 것입니다. 이러한 정보를 가지고 있으면 사용자 설정, 초기 폼 값 채우기, 방문 횟수의 기억과 같은 많은 일들을 수행할 수 있으며 페이지를 사용할 때 더 많은 정보를 사용자에게 제공할 수 있습니다.
쿠키는 웹사이트에서 상태를 관리할 수 있는 가장 강력한 방법 중 하나입니다.

'phpsource > 캐시&세션&쿠키' 카테고리의 다른 글

{쿠커}4.브라우저 설정  (0) 2001.02.20
{쿠커}3.보안  (0) 2001.02.20
{쿠커}1.쿠키란?  (0) 2001.02.20
{세션핸들러}3.업그레이드 및 패치  (0) 2001.02.02
{세션핸들러}2.사용방법  (0) 2001.02.02
Posted by 방글24
쿠키(cookie)
웹브라우저가 동작하고 있는 로컬시스템에 존재하는 하드디스크 영역 중 아주 작은 공간을 할당하여 이 곳에 웹서버와 지속적인 통신하는데 필요한 정보를 저장하게 되는데 이 곳에 저장된 정보를 쿠키라고 합니다. 이러한 쿠키는 name=value 형태의 단순한 텍스트 파일이기 때문에 실행되지 않으며 따라서 바이러스를 심는 것과 같은 동작은 절대 할 수 없습니다. 보통 웹사이트 방문객에 대한 정보를 저장하기 위해서 사용됩니다.
쿠키의 동작
< 쿠키의 동작 >
① 쿠키 기반의 웹문서 접근(URL 실행 요청)
쿠키를 보내주는 웹문서의 실행을 요청합니다.
② 브라우저에 쿠키 저장
웹프로그램은 브라우저에 해당 URL에 대해 쿠키의 NAME/VALUE값과 여러가지 정보들을 함께 전달합니다. 서버에서 클라이언트로 쿠키 정보를 보낼 때는 HTTP 응답헤더를 통해 보내게 됩니다. HTTP 응답헤더를 통해 브라우저로 전달된 쿠키는 쿠키명 및 값의 바이트수와 유효기간, 유효경로, 유효도메인 등을 확인한 후 사용자의 하드디스크 또는 메모리에 저장됩니다.
③ 지정된 URL에 대해 쿠키 전달
저장된 쿠키는 웹브라우저가 쿠키에 지정된 조건에 맞는 URL을 요청할 때, 쿠키에 대한 정보를 다시 서버에 보냅니다. 클라이언트에서 서버로 쿠키 정보를 보낼 때는 HTTP 요구헤더를 통해 웹서버로 전달됩니다. HTTP 요구헤더를 통해 웹서버로 전달된 쿠키는 HTTP_COOKIE라는 환경변수를 통해 CGI 프로그램으로 전달됩니다.
쿠키정보의 저장
브라우저가 웹서버로부터 쿠키 정보를 전달받으면, 이 정보들의 유효기간을 살펴 유효기간이 있는 쿠키는 쿠키 파일에 저장하고, 그렇지 않은 쿠키는 임시 버퍼 영역(메모리)에 저장합니다.
쿠키 파일에 저장된 쿠키 정보는 웹브라우저를 종료하더라도 다음에 다시 웹브라우저가 기동될 때 쿠키 파일의 내용이 메모리로 올려서 그 정보를 계속 사용할 수 있도록 합니다.
웹브라우저의 종료와 관계없이 지속적으로 유지되는 쿠키가 사용되는 경우 - 파일에 저장되는 경우 - 를 보면 제가 사용하고 있는 제로보드를 사용해 보면 됩니다. 제로보드 게시판에서 글쓰기를 하게 되면 최초에 입력하였던 NAME, E-MAIL, Homepage 내용이 다음 번에 다른 내용으로 글쓰기를 하려고 하면 자동으로 해당 필드가 채워져 있는 것을 볼 수 있을 것입니다. 이것은 최초에 글쓰기를 할 때(최초가 아닐 때도 마찬가지이지만) 입력하였던 필드값을 사용자 시스템에 쿠키로 저장시켜 놓았기 때문에 가능한 것입니다. 이러한 활용은 쿠키가 아니면 구현하기가 어렵겠죠. 동일한 로컬시스템으로 여러 사용자가 같이 사용하는 경우라면 오히려 불편할 수 있는, 때에 따라서는 위험하기도 한 기능이지만 한 사용자만 사용되는 로컬시스템에서 사용하기에는 아주 편한 기능이 될 것입니다.
반면에 메모리에 임시 저장되는 쿠키는 웹브라우저가 계속 살아있을 때만 쿠키값을 유지하게 되는 것입니다. 이러한 쿠키들은 웹브라우저의 종료와 함께 없어져야 하는 값들을 정의할 때 - 예를 들어 로그인할 때 작성된 회원ID 및 관련 정보들 - 유용하게 써먹을 수 있겠지요.
웹서버마다 독립적으로 동작되는 쿠키파일
이와 같이 서버는 웹브라우저의 쿠키에 특정 정보를 저장할 수 있으며, 일단 저장된 정보는 필요한 경우 언제든지 참조할 수 있습니다. 이러한 쿠키값은 각 서버 별로 독립적으로 유지관리되기 때문에 쿠키를 생성한 서버에서만 그 쿠키를 참조할 수 있으며 다른 서버에서는 이를 전혀 다룰 수 없습니다. 또한 쿠키는 웹브라우저를 통해 모든 쿠키 정보를 읽고 쓰고 삭제하게 됩니다. 이와 같은 쿠키에서 차지하는 웹브라우저의 엄청난 영향력으로 말미암아 브라우저 버전에 따라 버그로 인해 로컬시스템의 보안 문제가 발생한 적도 있습니다.
< 웹서버와 브라우저 쿠키파일의 관계 >
쿠키의 유용성
이전에 한번 입력하였던 정보를 웹브라우저가 기억하고 있다가 다음 번에 사용자가 웹 페이지를 다시 방문하면 기억하고 있는 정보를 가지고 웹페이지를 구성하기 때문에 사용자가 똑같은 정보를 다시 입력할 필요가 없습니다. 기껏해야 암호정도만 입력받아 필요한 서비스를 제공할 수 있습니다. 시간을 절약할 뿐만 아니라 사용자 확인을 위한 번거로움을 최소화할 수 있습니다.
사용자가 이전에 제공받았던 서비스를 분석하여 그 정보를 기초로 서버에서 보낼 웹 페이지를 구성하게 되면 사용자 구미에 맞는 정보를 제공할 수 있습니다. 예를 들어 사용자가 이전에 증권정보를 주로 검색하였다면 이와 관련된 정보를 첫페이지에 포함시켜 사용자에게 제공할 수도 있겠지요. 아니면 다른 광고에 앞서 증권 관련 광고를 먼저 표시할 수도 있겠지요. 이와 같이 사용자가 보고 싶어하는 정보를 빠르고 쉽게 접근할 수 있도록 하는 것이 중요하지 않을 까요?
쿠키가 사용자의 로컬시스템에 저장되므로 웹서버쪽에서 별도로 사용자 정보를 관리할 필요가 없다는 장점이 있기는 하지만 사용자가 임의로 이 파일을 삭제할 수 있으므로 서버 입장에서는 지속적으로 유지하여야 하는 사용자 정보를 담아두기에는 부적합하며 단지 일시적인 정보나 아니면 사용자의 허락하에 사용할 수 있는 정보를 저장하는 경우에 유용하게 사용할 수 있을 것입니다. 또 하나 사용자가 웹브라우저의 쿠키 동작을 꺼버릴 수도 있기 때문에 이 때는 서버에서 쿠키를 전혀 사용할 수 없게 됩니다. 따라서 이런 경우를 대비하여 웹사이트를 개발할 필요가 있습니다.
쿠키의 활용
회원인증
쿠키에 사용자 아이디와 암호를 넣어서 자신의 웹을 방문하는 사람들이 방문할 때마다 사용자 아이디와 암호를 넣지 않아도 되게 하는 것입니다. 물론 처음 한번은 해야겠지요.
카운터
쿠키를 이용하면 한 방문자에 대하여 페이지 히트수에 관계없이 단 한번만 카운트할 수 있도록 하는 카운터를 어렵지 않게 만들 수 있습니다.
장바구니
인터넷 쇼핑몰에서 사용자가 선택하는 물건들을 쿠키에 담아둘 수 있습니다. 물건 선택을 끝내고 구매할 때 쿠키에 저장된 물품 목록에 의해 비용 처리를 하게 됩니다.
알림창 표시
웹사이트에 들어온 방문자에게 알려야 하는 중요한 정보를 별도의 창을 이용하여 표시하는 경우가 많이 있습니다. 방문자에게 소식을 전하기에는 편하지만 방문자 입장에서는 웹사이트를 방문할 때마다 알림창을 계속 보아야 하는 것은 짜증나는 일입니다. 이럴 때 알림창에 체크 박스를 두어 다음부터는 창을 띄우지 않을 수 있도록 방문자가 선택할 수 있게 합니다. 체크 박스에 대한 정보를 쿠키에 담아 두면 현재 방문자는 알림창을 다시 볼 필요가 없겠지요
쿠키의 장단점
쿠키의 장점
쿠키의 가장 강력한 특징 중의 하나는 상태 유지에 있습니다. 쿠키가 사용자의 브라우저에 설정되고 나면 이 값은 특별한 일이 없으면(?) 결코 없어지지 않습니다. 이것은 사용자 설정이나 방문 정보를 쉽게 저장 할 수 있도록 해주며 사용자가 다시 사이트를 방문할 때 이 정보를 사용할 수 있도록 해줍니다.
쿠키의 단점
강력한 상태관리를 지원하는 장점을 가진 쿠키이지만 많은 브라우저가 쿠키 정보를 암호화 되지 않은 형태로 보관하기 때문에 패스워드와 같은 민감한 정보들을 쿠키에 저장할수 없다는 단점을 갖습니다. 사용자의 컴퓨터에 접근할 수 있는 누구라도 이러한 민감한 정보를 쉽게 얻을 수 있기 때문입니다.
브라우저가 허용하는 쿠키 파일의 크기나 수량이 제한되기도 하고, 브라우저의 동작 매커니즘에 따라 새로운 쿠키가 오래된 쿠키를 덮어쓰기도 합니다. 또한 쿠키 파일의 구조는 브라우저에 따라 다르기 때문에 여러 브라우저가 하나의 쿠키 파일을 공유할 수 없습니다.

'phpsource > 캐시&세션&쿠키' 카테고리의 다른 글

{쿠커}3.보안  (0) 2001.02.20
{쿠커}2.웹페이지 상태유지  (0) 2001.02.20
{세션핸들러}3.업그레이드 및 패치  (0) 2001.02.02
{세션핸들러}2.사용방법  (0) 2001.02.02
{세션핸들러}1.개요  (0) 2001.02.02
Posted by 방글24
세션핸들러 0.0.2p3(2001.5.31)
  • 데이터베이스용 세션핸들러 수정
    1. 미니디비 0.2.2p1와의 충돌을 피하기 위하여 수정하였으므로 미니디비 0.2.1을 사용하시는 분은 기존의 것을 계속 사용하시기 바랍니다.

    미니디비 0.2.2p1과 함께 업그레이드하여야 할 것은 다음과 같습니다.

    -미니디비 0.2.2p1
    -세셔너 0.2.5p1
    -데이터베이스용 세션핸들러 0.0.2p3

    2. magic_quotes 문자 처리에 문제가 발생하여 sessRead() 함수를 수정하였습니다.
세션핸들러 0.0.2p2(2001.4.14)
  • 공유메모리용 세션핸들러 추가
세션핸들러 0.0.2(2001.2.16)
  • 쿠키용 세션핸들러 추가
세션핸들러 0.0.1(2001.2.2)
  • session_set_save_handler(), session_module_name(), session_encoding(), session_decoding() 함수 추가
  • 세셔너함수 0.2.2와 세셔너클래스 0.0.3 통합 => 세셔너 0.2.3
  • 세션함수와 세션핸들러의 분리
  • PHP3와 PHP4 공용 세션핸들러의 외장모듈 별도 제공(파일시스템용, 데이터베이스용, DBM/DMA용)
  • PHP3와 PHP4 공용 세션핸들러 함수 제공 - session_handler(), session_guests(), session_guest_list(), session_guest_data(), session_guest_decode(), session_event_path()
  • PHP3와 PHP4 공용 이벤트 핸들러 OnStart 및 OnEnd 제공
  • 세션명, 세션파일명 디폴트값을 PHP4 세션과 동일하게 변경(PHPSESSID, sess_......)

Posted by 방글24
세션핸들러 파일
세션핸들러는 PHP3와 PHP4에서 모두 변함없이 사용할 수 있으므로 PHP4로 업그레이드하더라도 이 부분은 수정할 필요가 없습니다. PHP3에서는 세션함수를 제공하지 않으므로 제가 공개한 세셔너를 포함시켜야 합니다. 저장매체에 따라 또는 PHP 버전에 따라 포함하여야 하는 파일이 차이가 나므로 아래를 참조하여 적절한 파일을 선택하기 바랍니다. 파일을 인클루드하는 부분을 제외한 나머지 부분은 저장매체 또는 PHP 버전에 관계없이 동일합니다.
PHP3 - 세셔너 핸들러(파일시스템)
[code php;gutter:false] <?php

require("./sessioner/lib.sessioner.php");
require("./sessioner/handler.sessfile.php");

session_handler();
session_start();

.
.
.

?> [/code]
PHP4 - 세셔너 핸들러(파일시스템)
[code php;gutter:false] <?php

require("./sessioner/handler.sessfile.php");

session_handler();
session_start();

.
.
.

?> [/code]
PHP3 - 세셔너 핸들러(데이터베이스)
[code php;gutter:false] <?php

require("./minidb/class.mysql.php");
require("./sessioner/lib.sessioner.php");
require("./sessioner/handler.sessbase.php");

$base = new baseDbsql("localhost", "xx", "xx", "xx");

session_handler();
session_start();

.
.
.

?> [/code]
PHP4 - 세셔너 핸들러(데이터베이스)
[code php;gutter:false] <?php

require("./minidb/class.mysql.php");
require("./sessioner/handler.sessbase.php");

$base = new baseDbsql("localhost", "xx", "xx", "xx");

session_handler();
session_start();

.
.
.

?> [/code]
PHP3 - 세셔너 핸들러(DBM)
[code php;gutter:false] <?php

require("./sessioner/lib.sessioner.php");
require("./sessioner/handler.sessdbm.php");

session_handler();
session_start();

.
.
.

?> [/code]
PHP4 - 세셔너 핸들러(DBA)
[code php;gutter:false] <?php

require("./sessioner/handler.sessdba.php");

session_handler();
session_start();

.
.
.

?> [/code]
PHP3 - 세셔너 핸들러(쿠키)
[code php;gutter:false] <?php

require("./sessioner/lib.sessioner.php");
require("./sessioner/handler.sesscook.php");

session_handler();
session_start();

.
. 세션데이터 관련하여 서버에서 처리할 내용
.

session_write();

.
. 세션데이터를 이용만 할 수 있는 부분
.

?> [/code]
PHP4 - 세셔너 핸들러(쿠키)
[code php;gutter:false] <?php

require("./sessioner/handler.sesscook.php");

session_handler();
session_start();

.
. 세션데이터 관련하여 서버에서 처리할 내용
.

session_write();

.
. 세션데이터를 이용만 할 수 있는 부분
.

?> [/code]
사용 예제(PHP3에서 데이터베이스용 세션핸들러를 사용할 경우)
[code php;gutter:false] <?php

/*
filename : sessbase.php3
email : hwooky@phpclass.com
homepage : www.phpclass.com
author : hwooky
environment :
PHP3
미니디비 0.2.1
세셔너 0.2.3
세션핸들러(디비용) 0.0.2
*/

require("./../../engine/class2/minidb/class.mysql.php");
require("./../../engine/class2/sessioner/lib.sessioner.php");
require("./../../engine/class2/sessioner/handler.sessbase.php");

$base = new baseDbsql("localhost", "xx", "xx", "xx");

session_event_path("./event");
session_handler();
session_start();

if ($init) {
session_unset();
session_destroy();
session_handler();
}

if (!$bank) {
session_register(array("bank", "bank2", "bank3"));
}

//
// 서버에서 처리해야 할 부분
//
$bank .= "#";
$bank2 += 10;
$bank3 .= "$";

session_write(); // 쿠키용의 경우에는 이곳에서 세션데이터를 쿠키로 저장하며,
// 파일용,디비용,DBM/DBA용의 경우에는 이 함수를 무시하며
// 웹문서 처리가 끝나는 시점에서 세션데이터를
// 해당저장매체에 저장

//
// 브라우저에 보낼 데이터를 생성하는 부분
//

echo "==============\n";
echo "Sesseiner Path : ".session_save_path()."\n";
echo "==============\n";
echo "이벤트핸들러 정보 :\n";
echo $event_test;
echo "==============\n";
echo "세션데이터 정보 :\n";
echo "\$bank = $bank\n\n";
echo "==============\n";
echo "타방문자 정보 :\n";
$list = session_guest_list();
if (is_array($list)) {
echo "타방문자수 : ".session_guests()."명\n";
while(list(,$id)=each($list)) {
$vars = session_guest_decode(session_guest_data($id));
echo "\$id=$id\n";
while(list($k,$v)=each($vars))
echo " $k=$v\n";
}
}
echo "==============\n";

echo "\n<A href=$PHP_SELF>반복실행</A>";
echo "\n<A href=$PHP_SELF?init=y>세션 초기화 후에 재실행</A>";

?> [/code]
세셔너 파일을 인클루드시키는 부분만 추가될 뿐이며 다른 것은 PHP4 세션 함수를 사용하는 방법과 동일합니다. 따라서 예제 코드에서 세셔너 파일을 인클루드하는 부분만 삭제하면 PHP4에서도 정상적으로(동일하게) 동작합니다.
위 예제에서 session_write() 함수는 쿠키용 세션핸들러에서만 필요한 함수입니다. 쿠키용이 아닌 세션핸들러에서는 이 함수를 사용하더라도 무시되며 이때문에 에러를 발생시키지는 않습니다. 이 함수에 대한 자세한 설명은 앞장을 참조바랍니다.
이벤트 파일 예제(event.sessioner.php)
위의 예제에서 사용된 이벤트 파일은 아래와 같습니다. session_event_path("./event")에 지시한 대로 현 웹문서가 있는 디렉토리에 있는 "event"라는 디렉토리에서 이벤트 파일을 찾게 됩니다.
[code php;gutter:false] <?php

function sessioner_onStart() {
static $i = 0;
$GLOBALS[event_test] .= "$i)sessioner_onStart()\n";
$i++;
}

function sessioner_onEnd() {
static $i = 0;
$GLOBALS[event_test] .= "$i)sessioner_onEnd()\n";
$i++;
}

?> [/code]

Posted by 방글24