세션(session)이란?
세션이란 용어는 방문자가 특정 웹사이트에 머무르게 되는 일정 시간을 뜻합니다. 앞장에서도 언급했었지만 문제는 HTTP는 상태를 유지하는 기능을 갖고 있지 못하므로 각각의 요청은 서로와 관련성을 갖지 못한다는 점입니다. 웹서버는 쉽게 각각의 방문자를 구분하지 못하고 특정 방문자의 세션에 대하여 알 수가 없습니다. FTP 또는 TELNET와 다르게 HTTP(Hyper Text Transfer Protocol)는 방문자의 상태를 계속 유지할 수가 없는 문서텍스트의 비순차적 검색을 위한 인터넷 프로토콜로 TCP/IP를 기반으로 하고 있으며 파일 단위의 요청, 연결, 송수신을 기본으로 하고 있습니다. 따라서 새로운 페이지를 요청할 때마다 새로운 접속이 이루어지며 이전페이지와 현재페이지의 관계가 지속되지 않습니다. 이에 따라 HTTP 프로토콜을 이용하게 되는 웹사이트에서는 웹페이지에 머무르는 특정 방문자가 머무르는 동안에 그 방문자가 가지고 있어야 하는 데이터를 묶는 방법이 필요하게 됩니다. 이 방법을 세션 관리라고 합니다. 결국 세션이란 특정 방문자가 특정 시간에 접근하는 기간을 똣하는 것으로, 로그인하는 순간부터 회원전용 서비스를 이용하는 시간을 거쳐 로그아웃할 때까지의 시간을 말합니다. 회원인증ID 발급부터 회원인증ID 삭제까지의 과정을 세션이라고 하며 이 과정에서 유지되어야 하는 정보를 세션정보라 할 수 있습니다.
< 세션 생성 및 소멸 >
그림에서 보면 전체 시간 중에 5명의 방문자가 웹사이트에 접속하여 로그인-로그아웃하기를 반복하여 총 8개의 세션이 발생한 후 소멸되었습니다. 동일 시간 대에 발생한 최대 세션수를 보면 4개로 나타나 있습니다. 이러한 세션 중에 유지되는 정보가 세션 정보이고, 이러한 정보가 저장되어야 하는 변수를 세션 변수라고 합니다. 그리고 세션과 세션을 구분하는데 필요한 식별자를 세션 ID라고 합니다.
세션 정보
회원인증ID를 통한 서비스를 제공받을 때에 대부분 한 페이지에서만 서비스를 받는 경우는 거의 없으며 대부분 2페이지 이상의 복수 페이지에서 받게 됩니다. 따라서 발급된 회원인증ID를 다른 페이지로 계속 전달할 필요가 있으며 이렇게 하여야 한번의 인증과정(로그인과정으로 회원인증ID를 발급하는 과정)만으로 방문자는 더 이상 자신을 인증하기 위해 회원ID와 비밀번호를 다시 입력할 필요가 없게 됩니다. 이와 같이 복수의 페이지에서 한번 발급된 회원인증ID를 유지하기 위한 방법이 필요하게 되며, 이러한 방법으로는 많은 경우가 쿠키 또는 세션함수를 이용하게 됩니다. 회원인증ID 외에도 서비스를 받는 동안 발생하는 각종 정보 중 그 값이 세션중에 계속 유지되어야 하는 세션정보에는 로그인 과정 중에 회원 데이터베이스에서 읽어온 회원정보, 쇼핑몰 사이트인 경우에는 장바구니, 통계 분석을 위해 수집되는 방문자 PC에 대한 정보 등이 있습니다. 이렇게 회원을 가입받고, 로그인하게 한다면 세션 정보를 이용해서 각각의 사용자들을 구별할 수가 있을 것입니다. 이 회원인증을 통해 우리는 각각의 사용자가 어떤 사람이냐에 따라 페이지 접근을 제한할 수도 있습니다. 세션 내에서 유지되어야 하는 세션 정보는 아래와 같이 분류될 수 있습니다.
회원정보(Member) - 로그인할 때 회원 데이터베이스로부터 읽어 온 회원에 대한 정보
세션정보(Session) - 세션아이디(PK) 회원아이디.레벨.그리고 통계를 위한 자료들
회원선택정보 - 쇼핑몰에서의 장바구니 정보(제품아이디 세션아이디 수량 등),
회원제 강의실에서의 수강신청과목 등과 같이 회원이 서비스
받은 동안 선택하게 되는 정보, 방문자가 접근했던 페이지 이력 등
이 중에 회원선택정보에는 세션 내에서 뿐만아니라 동일 방문자(물리적 의미에서의)가 향후에 접근하게 되는 또 다른 세션에서도 유지할 필요가 있는 정보가 있으며, 이러한 정보는 세션이 종료되기 전에 데이터베이스 등을 이용하여 영구적으로(또는 반영구적으로) 보존하기 위한 대책을 강구하여야 합니다.
세션 관리
특정 방문자에 대한 세션 정보를 세션 내에서 유지하는 방법(즉, 페이지간 세션정보를 전달하는 방법)에는 아래와 같이 여러 가지가 있습니다.
-
쿠키를 이용하는 방법(PHP3 & PHP4)
-
세션함수를 이용하는 방법(PHP4)
-
쿠키와 데이터베이스를 이용하는 방법(PHP3 & PHP4)
-
HTTP GET & POST Method(PHP3 & PHP4)
PHP3에서는 쿠키를 가장 많이 애용했을 겁니다. PHP4에서는 세션함수를 많이 이용할 거라고 추측됩니다. 그리고 PHP4가 발표되기 전에 사용되던 PHPLIB와 같은 세션라이브러리는 3번째 방법에 해당합니다. PHP3와 PHP4에서 모두 동작하기를 원하면서 다량의 정보를 전달할 필요가 있을 때에 3번째 방법이 가장 적합한 방법이 되겠지만 이 방법은 개발자가 손볼게 많은 것이 흠이지요. PHP4에서만 동작되어도 상관없다면 2번째 방법으로 개발하시는 것이 가장 좋을 듯합니다. 사용하기도 편하고 기본적으로 PHP 스크립트에 내장된 함수들이라 향후 호환성도 보장되고요. HTTP GET & POST 방식으로도 세션 관리를 할 수도 있지만, 이 방식을 사용하면 매페이지에서 모든 세션 정보를 계속 다음 페이지로 전달하여야 하는 문제가 있어 특별한 경우가 아니라면 별로 바람직하지 않습니다.
쿠키(Cookie)를 이용한 세션 관리
쿠키(cookie)는 세션정보를 서버가 아닌 방문자의 시스템(하드디스크)에 저장함으로써 서버쪽에서 해당 방문자를 다른 방문자와 구분하여 추적할 수 있도록 해 주는 것으로, setcookie() 함수를 이용하여 이러한 쿠키를 생성합니다. 본 문서에서는 setcookie() 함수에 대해서 별도로 기술하지 않겠습니다. 따라서 관련 웹사이트나 자료를 참고하여 setcookie() 함수에 입력되는 각 인자를 설정하여 주시기 바랍니다. 아래는 예를 들어 나타낸 인자들이므로 실제 상황에서는 다르게 설정될 수 있습니다.
[code php;gutter:false]
SetCookie("member_id",$id,0,"/");
SetCookie("member_name",$db_name,0,"/");
SetCookie("member_email",$db_email,0,"/");
SetCookie("member_homepage",$db_homepage,0,"/");
[/code]
회원전용 서비스를 제공하는 페이지에서 세션정보를 이용하게 되는데 이 때 쿠키로 저장된 세션 정보를 읽어 오기 위해서는 보통 쿠키를 위한 배열변수인 $HTTP_COOKIE_VARS[]를 이용하게 됩니다. 만약 보안상의 문제를 무시하셔도 된다면 배열 $HTTP_COOKIE_VARS[] 대신에 $member_id와 같이 전역변수로써 처리하시는 것이 편할 것입니다.
[code php;gutter:false]
echo $HTTP_COOKIE_VARS["member_id"];
echo $HTTP_COOKIE_VARS["member_name"];
echo $HTTP_COOKIE_VARS["member_email"];
echo $HTTP_COOKIE_VARS["member_homepage"];
[/code]
그리고 로그아웃할 때 아래와 같이 쿠키정보를 삭제합니다.
[code php;gutter:false]
if ($HTTP_COOKIE_VARS["member_id"]) {
SetCookie("member_id","",time());
SetCookie("member_name","",time());
SetCookie("member_email","",time());
SetCookie("member_homepage","",time());
}
[/code]
쿠키값을 읽을 때 배열변수 $HTTP_COOKIE_VARS["cookie_name"] 대신에 전역변수 $cookie_name를 사용할 수도 있으나, test.php?cookie_name=val과 같이 GET 또는 POST 등과 같은 방법으로도 전역변수 $cookie_name의 값이 넘어 올 수 있으므로 보안상 별로 바람직하지 않습니다.
쿠키 기술은 넷스케이프 내비게이트에서 처음 사용됐으며, 뒤이어 MS 익스플로러에도 쿠키 기술이 탑재되었습니다. 현재 대부분의 웹브라우저는 쿠키 기능을 갖고 있습니다. 그런데 방문자가 쿠키를 받을 것인지 아닌지를 선택할 수 있는 기능도 포함되어 있기 때문에 만약 방문자가 쿠키를 받지 않도록 브라우저가 설정한다면 쿠키를 이용한 세션 관리는 불가능합니다. 따라서 개발자는 이 경우를 고려하여 웹사이트를 개발하여야 할 것입니다.
쿠키를 이용할 때 고려해야 할 또 한가지 중요한 것은 setcookie() 함수의 세번째 인자인 시간 설정에 관련된 문제입니다. setcookie() 함수로 설정되는 시간은 서버 시간을 기준으로 지정되지만 쿠키가 생성되고 소멸되는 시간은 방문자 시스템(클라이언트) 시간을 기준으로 수행됩니다. 따라서 서버와 클라이언트 시간 설정이 일치하지 않는다면(대부분은 아마 정확히 일치하지 않을 것입니다만) setcookie() 함수를 이용하여 쿠키를 클라이언트에 정확한 시간에 생성 및 소멸시키는 것은 매우 어려울 것입니다. 이 문제는 결국 로그인이 정상적으로 이루어지지 않는다는 문제와 같다고 할 수 있으므로 웹사이트 개발자는 쿠키를 사용할 때는 이 문제를 충분히 고려하여야 합니다.
세션 함수(PHP4 세션)를 이용한 세션 관리
쿠키는 방문자가 알지 못하는 사이에 방문자의 동의없이 신상정보를 방문자의 컴퓨터에 저장하고 이 정보를 제 3자에게 전달할 수 있습니다. 이 문제로 인해 개인의 프라이버시를 침해할 소지가 다분이 포함되어 있고, 또한 보안 문제도 나타나고 있는 것으로 보여집니다. 이러한 문제로 인하여 세션 상태를 웹브라우저가 아닌 웹서버에 기록할 필요성이 대두되어 이에 대한 방법으로 PHP 스크립트에서는 세션 함수를 제공하고 있습니다. 그러나 이러한 세션함수들은 PHP4에서 부터 지원되는 기능으로 PHP3에서는 지원되지 않기 때문에 현재(2000.10)까지는 아직 대다수를 차지하고 있는 PHP3 스크립트에서는 이용할 수 없는 문제가 있습니다.
PHP4 세션은 session_start() 함수로 시작할 수도 있고, session_register() 함수를 사용하여 세션 변수를 등록함으로써 시작될 수도 있습니다. session_start()는 페이지 맨 위에서 호출되며, 등록된 세션 변수를 스크립트에서 사용할 수 있도록 해주며, session_register() 함수는 새로운 세션 변수를 등록할 수 있도록 해줍니다. 세션이 시작되지 않았다 하더라도 session_register() 함수가 내부적으로 session_start()을 호출하기 때문에 특별히 session_stert() 함수를 명시할 필요가 없습니다. 세션함수는 PHP 스크립트에 내장되어 있기 때문에 인증, 퍼미션, 사용자 로그인에 따른 세션값, 페이지 관리 등을 보다 빠르고 편하게 할 수 있습니다.
아래와 같이 session_register를 이용하여 세션 정보를 등록합니다.
[code php;gutter:false]
session_register("member_id");
session_register("member_name");
session_register("member_email");
session_register("member_homepage");
$member_id = $id;
$member_name = $db_name;
$member_email = $db_email;
$member_homepage = $db_homepage;
[/code]
회원전용 서비스를 제공하는 페이지에서 세션정보를 이용하게 되는데 이 때 서버에 저장된 세션 정보를 읽어 오기 위해서는 session_start()함수를 이용하게 됩니다.
[code php;gutter:false]
session_start();
echo $member_id;
echo $member_name;
echo $member_email;
echo $member_homepage;
[/code]
그리고 로그아웃할 때 아래와 같이 session_destroy() 함수를 이용하여 세션 정보를 삭제합니다.
[code php;gutter:false]
session_destroy();
[/code]
PHP을 설치할 때 특별히 설정값을 변경하지 않았다면 세션 변수의 지속시간은 0입니다. 따라서 브라우저를 닫는 순간에 세션은 종료되어 등록된 세션변수들은 모두 사라지게 됩니다.
쿠키와 데이터베이스를 이용한 세션 관리
PHP3 스크립트에서는 세션을 구현할 수 있는 함수가 별도로 제공되지 않았기 때문에 보통 쿠키를 이용하여 세션을 구현하였습니다. 또 다른 방법으로는 PHPLIB 라이브러리와 같이 데이터베이스를 이용하여 세션 기능을 구현하게 됩니다. 각 방문자를 구별해 주는 세션 ID는 PHP4 세션과 마찬가지로 쿠키 또는 GET/POST Method 등을 이용하게 되며, 세션 정보를 저장하기 위한 수단으로 사용되는 데이터베이스로는 MySQL, 오라클, 포스트그레스 등과 같이 우리가 알고 있는 대부분의 데이터베이스를 이용할 수 있습니다. PHPLIB는 이와 같이 다양한 도구를 이용할 수 있도록 작성되어 있어 확장성이 좋은 반면에 코드가 너무 복잡하고 이해하기도 쉽지않아 이를 이용하여 세션 기능을 구현한 경우는 그리 흔하지 않은 것 같습니다. 그래서 이를 축소하여 쿠키와 MySQL을 이용하여 세션을 구현하도록 한 축소판 세션 라이브러리(곽태환 님의 세션 라이브러리 또는 제 홈페이지에 있는 세션 라이브러리)도 일부 공개되고 있습니다. 각 라이브러리의 사용 방법은 라이브러리마다 서로 다르기 때문에 여기서는 사용 방법을 언급하지 않겠습니다. 그러니 궁금하시면 각 라이브러리를 참고하시기 바랍니다.
HTTP GET 방식을 이용한 세션 관리
세션 내의 페이지간에 세션 변수를 HTTP GET Method를 통해 지속적으로 전달하여 세션을 관리할 수 있습니다. GET Method로 변수값을 전달하는 방법으로는 아래와 같이 3가지 방법이 있습니다.
[code php;gutter:false]
echo ("<SCRIPT>location.href='page.php3'</SCRIPT>") ;
[/code]
< 1) 자바스크립트를 이용하는 방법 >
[code php;gutter:false]
<?php Header("Location:page.php3") ; ?>
[/code]
< 2) 헤더 함수를 이용하는 방법 >
[code php;gutter:false]
echo ("<META http-equiv='refresh' content='0; url=./index.html'>") ;
[/code]
< 3) 메타 태그를 이용하는 방법 >
GET 방식은 서버 또는 브라우저에서 변수와 그 값이 모니터링될 수 있기 때문에 보안에 문제가 있습니다. 이러한 문제로 회원인증ID가 노출되었다면 호기심 많은 일부 사용자가 아래와 같이 프로그램을 실행하여 회원전용 페이지에 로그인없이 접근할 수 있을 겁니다.
page.php3?member_id=$id&member_pw=$pw
HTTP POST 방식을 이용한 세션 관리
다음과 같이 FORM 태그를 이용하여 변수를 전달합니다.
[code php;gutter:false]
echo ("
<form name='fc' action='./php_pro.php' method='post' >
<input name=fcurl type=hidden value='./basket.php'>
<input name=fwr type=hidden value='smile'>
</form>
")
[/code]
이렇게 하면 POST 방식으로 변수를 보낼 수 있고 게다가 INPUT 태그만 추가하면 얼마든지 많은 양의 변수를 보낼 수 있습니다. 게다가 환경변수 HTTP_POST_VARS[] 배열을 사용하여 GET으로 넘어오는 모든 변수를 막으면 보안에도 어느정도 대비할 수 있습니다. 단점이라면 매 페이지마다(현재 페이지에서 세션 정보를 사용하지 않더라도) 위의 코드를 포함시켜 다음 페이지로 세션 정보를 계속 전달하여야 합니다. 코드가 복잡해지고 때에 따라서는 불필요한 코드가 추가되어야 하는 것이지요.
[code php;gutter:false]
echo HTTP_POST_VARS["member_id"];
[/code]