메뉴 건너뛰기

프리그래밍 PHP - 세션, 쿠키 정리

까치 2014.04.22 18:15 조회 수 : 467

Session 정의

 

1. PHP3에서는 외부 모듈을 통해 세션 사용 가능, PHP4에서는 자체 세션 지원

 

2. HTTP프로토콜을 이용하여 웹서버에 웹페이지를 요청할시 각 요청자(접속자)를 구분하기 위해서 사용자의 컴에 쿠키로 발급하면서 동시에 같은 정보를 서버에는 세션으로 저장하여 웹서버는 쿠키와 세션을 비교해가면서 같으면 서버의 세션정보를 참고하여 사용자를 식별한다.

(HTTP프로토콜은 비연결 지향적인 프로토콜이라 페이지 응답후 끊어진다. 그래서 세션이 필요함) 

 

3. 세션(Session)의 의미 : 어떤 유저가 어떤 특정 사이트를 접속하여 머물러 있는 시간.

웹서버는 서로 다른 유저들로부터 서버 내에 있는 페이지를 요청이 들어올 경우에 각 유저들의 컴퓨터에 유일무이한 식별키를 쿠키의 형태로 발급하여 해당 유저가 사용자의 정보 즉,  사용자의 로그인이나 기타 입력된 정보를 서버 내에 저장하여 유저가 다시접속하였을때 유저에게 발급한 식별키를 이용하여 서버쪽에 저장해놓은 정보(세션값)를 가져옴으로써 유저를 구별하는 원리로 구현된다고 볼수 있다.

출처:http://spaceufo.wordpress.com

 

세션(Session)과 쿠키(Cookie)의 차이점

 

쿠키(Cookie) : 모든 유저나 회원들의 정보를 사용자의 시스템에 저장한다.
세션(Session): 유저의 데이터를 서버쪽에 저장하여 유저의 시스템에는 서버에 저장되어 있는 해당 사용자의 데이터를 찾아서 가져올 수 있는 식별키만(쿠키형태)를 저장하기 때문에 유저의 신상정보나 귀중한 정보가 밖으로 빠져나가는것을 막을수 있어 보안측면에서 좀더 안전하다. 

출처:http://spaceufo.wordpress.com

 

현재 설정된 세션 유지시간 보기(단위:분)

<?= session_cache_expire(); ?>

 

세션 유지시간 설정하기

<?

//# session_start() 전에 사용해야함\

//# 세션유지시간:30분 설정

session_cache_expire(30);

session_start();

?>

 

SESSION 이 필요한 이유

 

인터넷 즉 웹은 HTTP을 이용해서 웹파일을 송수신합니다.

근데 HTTP는 비연결지향형 프로토콜로서 웹파일의 전송이 끝나면 접속이 끊어집니다.

HTTP는 상태를 구별하지 않는 프로토콜이며 이것은 웹 서버가 페이지에 대한 브라우저의 HTTP요청을 독립적으로 각각 처리하여 취급한다는 의미입니다.

즉 이전 HTTP 요청이 발생한 지 불과 몇 초 후에 다시  HTTP 요청이 발생하더라도 서버에는 이전 요청에 대한 정보가 남지 않습니다.

그래서 각요청자가 요청한 HTTP요청을 웹서버가 구별하기 위해 SESSION을 사용합니다.

※ FTP는 연결지향적 프로토콜이라고 합니다.

이는 접속, 처리(업로드,다운로드), 접속해제때까지 서버와 연결되어 있어 연결지향적 프로토콜이라고 부릅니다. 그래서 서버는 각각의 접속자를 구별할수 있습니다.

(어떤 접속자인지 알수 있다는 뜻입니다.)

 

Session 및 Cookie 선언 및 사용시점

 

세션은 세션을 만든 페이지와 그외의 페이지에서 출력이 가능하다.

세션은 session_start(); 함수전에 화면출력이 있으면 에러가 발생합니다.

Session_Start();함수 사용후에 화면출력을 해야 합니다.

 

쿠키는 쿠키를 만든페이지에서는 출력이 안되며 그외의 페이지에서 출력이 가능하다.

쿠키는 SetCookie함수 사용전에 화면출력이 있으면 에러가 발생합니다.

쿠키는 SetCookie함수 사용전에 공백이나 출력물이 있으면 에러가 발생합니다.

SetCookie함수 사용후에 화면출력을 해야 합니다.

 

※ session_start와 setcookie사용전에 화면출력이 되면 헤더가 전송되기전에 화면에 출력이 되므로 브라우저는 에러를 발생시킵니다.

 

Session 원리

 

1. PHP에서는 3가지 방식으로 세션을 사용가능

 

2. SESSION을 만들게되면 먼저 서버에 세션변수가 만들어집니다.

파일기반의 세션이라면 폴더에 파일형식으로 만들어집니다.

세션변수의 파일이름은 해당 방문자(접속자)의 유일한 SESSION_ID()명으로 만들어지며

세션변수의 내용은 세션을 만들시 넣을 값이 저장됩니다.

그다음에 SESSION을 만든 사용자의 컴퓨터에 세션쿠키가 저장됩니다.

세션쿠키변수에는 해당 방문자의 세션아이디가 저장됩니다. 

 

3. 세션이 만들어진후 세션이 필요한 페이지를 방문시 원하는 세션변수명을 사용자의 세션아이디로 만들어진 파일내용을 검색한후 있으면 사용자의 세션쿠키의 세션아이디값과 비교해 맞으면 사용자확인되었다고 판단하여 서버의 세션변수값을 보여주게 됩니다.

 

※ 보통 브라우저에서 쿠키를 사용안함으로 하면 세션도 동작하지 않습니다.

 

SESSION 유지 방법

 

1. 세션을 사용한 브라우저에 메뉴의 "파일/새로만들기/창" 을 이용해 새창을 열거나 링크부분에서

오른쪽 마우스로 "새창에서열기"로 새창을 열었을땐 세션이 유지되어 있다.

※ 하지만 익스플로어 아이콘을 통해 새창을 열면 현재 세션을 잃어 버리고 새로운 세션을 얻게 된다.

※ 팝업창도 세션이 생성된 브라우저에서 열리면 그대로 세션이 유지됩니다.

 

2. 현재 브라우저에서 주소표시줄에 다른 URL을 쳐서 이동을 해도 세션이 유지되지만 세션 유지 시간을 넘기면 자동으로 세션이 소멸됩니다.

 

3. 세션을 생성한 페이지나 그이후에 페이지에서 유지시간동안 페이지 이동이 없다면 자동으로 세션이 소멸됩니다.

 

4. 세션을 생성한 브라우저을 닫으면 세션도 소멸됩니다.

 

PHP 세션 매커니즘

 

우리가 해당사이트 접속하게 되면 해당 페이지에서 세션변수를 발생시키게 되면 서버에는 고유의 세션아이디가 생성되며 동시에 사용자의 컴에는 쿠키형태로 세션쿠키가 만들어지고 그안에는 세션변수의 값이 아닌 세션아이디명이 저장됩니다. 사용자에 의해 생성된 세션은 사용자에게 쿠키형태로 저장된 쿠키 안의 내용인 세션고유아이디와 서버상의 세션파일명이 같으면 이사용사는 해당 세션변수를 볼수있다고 판단하여 서버의 세션파일명에 실제 데이타를 참고합니다.

그래서 쿠키를 지원못하면 세션도 사용할수없습니다. 왜냐하면 매칭을 시킬 쿠기가 없기때문에 매번 비교시 다르기 때문입니다. 단지 차이가 있다면 세션은 실제 정보가 서버에 저장이 되지만 쿠키는 실제데이타가 클라이언트에 저장이 됩니다.

 

세션 저장방법

 

첫번째, 사용자의 데이터를 환경설정 파일(PHP.ini)에서 지정한 디렉토리에 파일로저장하는 방식으로 가장기본적인 방법이라고 할수 있습니다. 자 예를 들어 유저의 시스템에 저장한 식별키가 "0cd9cdv1vdf4fd4"이라면 서버 내 지정한 디렉토리에는 "sess_0cd9cdv1vdf4fd4"라는 이름을 갖는 파일로 생성하게 됩니다. 그러므로 식별키가 "0cd9cdv1vdf4fd4"인 유저가 사이트에 접속했을때 서버에서는 이 식별키에 해당하는 파일을 열어 해당사용자의 정보를 가져오게 되는 방법입니다.

 

두번째, 서버의 파일이 아닌 서버의 메모리에 저장하는 방식으로 파일로 저장하는 방법보다,높은 성능을 기대할수 있습니다. 특징으로 접속한 유저의 시스템에 식별키를 발급할 때 32개의 문자열로 이루어진 세션 아이디를 생성한다는 점입니다. 이 값은 유저의 시스템에 저장되며 유저가 서버에 접속했을 때 브라우저를 통해 서버에 자동 전송되므로 서버쪽에서 웹사이트에 접속해 있는 유저를 서로 구별할 수 있는 근거가 됩니다.

 

세번째, 사용자가 직접 세션을 다루는 방식을 정의하는 방법으로 보통 이 방법을 이용하여 세션 데이터를 파일이나 메모리,혹은 데이타베이스에 저장하여 관리하는 방법입니다. 세번째 방식의 특징은 이렇게 생성한 세션 아이디값은 보통 쿠키 방식을 통해 사용자의 시스템에 저장한다는 점입니다. 그러나 만약에 유저의 브라우저가 쿠키를 허용하지 않도록 설정되어 있다면, 이방식은 아무런 의미가 없겠죠!따라서 이때에는 쿠키가 아닌 다른 방식으로 웹서버에 사용자의 식별키를 전달 할 수 있는 방법을 사용해야 하며 이럴 경우 보통은 웹페이지 요청시에 세션 아이디값을 get이나 post방식을 통해 함께 전달해주는 방식을 사용합니다.

 

세션 시작하기

 

<? 
session_start()
?>

 

이렇게 세션함수를 호출하면 유저의 시스템에 이전에 발급된 유효 세션이 있는지 확인하게 되고, 검사결과 이전값이 없다면, 새로 세션아이디를 생성하고 이전에 발급한 아이디가 있고, 유효하다면, 서버에 저장한 데이터를 그대로 사용하게 되는것입니다.

 

이때 반드시 알아야 할점은 사용하고자하는 스크립트 최상단에 호출해주어야 합니다.이 함수를 호출하기 전에는 어떤한 함수의 실행결과나 html코드도 먼저 브라우저에 전송되어서는 안된다는얘기죠.. 왜냐면 이 함수는 사용자의 시스템에 세션 아이디를 쿠키의 형태로 발급하기 때문입니다.
만약 이함수를 호출전에 다른 태그를 사용할경우 아래 그림과 같은 메세지가 나올것입니다. 
세션을 사용하기를 원하는 페이지에는 무조건 맨위에 sessioin_start()를 해줘야 합니다.

 

세션이 안먹힐때

 

1)웹브라우저의 메뉴에서 도구/인터넷옵션/보안/기본수준이 높음 인경우
2)웹브라우저의 메뉴에서 도구/인터넷옵션/개인정보에서 설정이 모든 쿠키 차단 인경우

 

세션 변수 등록하기(2가지)

 

session_start()

$name="leejunsik";

$id="ysaraha";

session_register("name");

session_register("id");

//위는 변수 등록과 세션 등록이 2단계이다.

 

session_start()

$_SESSION["nme"]="sunz";

$_SESSION["id"]="sunz";

//아래는 세션 등록과 대입이 1단계이다.

 

※ register_globals = off일때 구형을 사용하면 나타나는 에러
Warning: Unknown(): Your script possibly relies on a session side-effect which existed until PHP 4.2.3. Please be advised that the session extension does not consider global variables as a source of data, unless register_globals is enabled. You can disable this functionality and this warning by setting session.bug_compat_42 or session.bug_compat_warn to off, respectively. in Unknown on line 0

 

※ 첫번째방법은 구형 방식이며 두번째 방식은 신형 방법이다.

두방법의 가장큰 차이는 register_globals가 off 인상태에서는 구형방법이 제대로 실행 안될수도 있다 그래서 신형 방법을 선택해야 register_globals가 on이나 off인 상태에서도 사이트가 잘돌아간다.

 

※ session_register 보다는 $_SESSION['id']="값"; 을 쓰시는게 나을것 낫습니다.

session_register는 에러리포팅을 강화시켜놓으면, waring 메시지가 뜹니다.

하지만 $_SESSION[]을 이용하면 waring 메시지가 뜨지 않습니다.

 

세션 변수 삭제하기

 

session_unset();

 

session_unset("변수");

 

※ session_unset 함수에 인자를 입력안하고 사용하면 전제 세션변수가 소멸된다.

 

※ session_unset 함수에 인자를 넣어 특정한 세션변수만 소멸을 해도 이상하게 전체가

소멸되는 버그가 있는거 같다. 이때는 session_unregister 함수를 이용하면 개별적으로

세션변수 소멸이 가능하다.

 

session_unregister("변수");
session_unset 현재 변수의 값을 삭제하고 변수도 소멸시키는 함수
session_unregister랑 다른점은 변수는 그대로 두고 변수값만 지운다는것입니다. 

session_destroy();는 현재 모든 세션의 변수값을 없애고 변수도 소멸시킨다.

session_is_registered 세션 변수가 현재의 세션에 등록되어 있는지를 조사하는 함수
session_is_registered("string name") 

 

※ session_destroy(); 보다는 session_unset();과 session_unregister();를 사용하는 습관을 기르자

※ unregister보다는 unset을 사용합니다.

※ session_destroy();을 사용하면 해당 페이지에서는 새로 세션을 생성할수 없다.

 

session_save_path 세션 데이터 파일 저장되어 있는 경로를 반환하거나 지정한 디렉토리로 변경하는 함수
보통기본값은 /tmp 디렉토리로 설정되어있습니다.
여기서 유의해야할사항 몇가지! 
①php.ini파일에 보시면 session.save_path = /tmp 이라는 옵션이 있는데 이것은 리눅스나 유닉스에 해당하는 디렉토리므로, 윈도우라면 D:/tmp 이런식으로 수정해야 합니다. 
②또한 변경하고 하는 디렉토리가 실제 존재해야 하며 디렉토리 권한 은 반드시 777로 해주셔야 합니다.
③이런식으로 디렉토리를 변경할경우에는 해당 세션과 관련된 데이터를 참조하는 모든 스크립트에 session_save_path()함수를 호출해주셔야 합니다.
④마지막으로 세션을 시작하는 session_start()함수 전에 이값을 호출해주셔야 합니다. 

 

session_id 현재의 세션 아이디를 반환하거나 지정한 값으로 변경하는 함수, 현재사용하는 세션 아이디를 구할때나 사용하죠.. 

 

session_module_name 세션 데이터 다루는 저장 방식에 관한 정보를 반환시키는 함수
첨에 세션의 저장방식에 대해서 설명드릴때 3가지 방법이 있다고했죠,파일저장방법, 메모리저장바업,사용자가 세션을 다루는 방법을 직접정의하는방법이 세가지 방법을 값으로 변환해주는 함수입니다. 이 함수도 PHP환경설정 파일(php.ini)내에서 수정이 가능합니다.

session.save_handler = files; <---기본값이죠

 궁그미 전에도 답변한적이 있는데 gc옵션은 garbage collection을
설정하는거지 세션의 유지 시간과는 상관없습니다.
죽은 세션문서를 정리하는 옵션이죠.

 

실제로 세션 유지 시간은 session.cache_expire 이부분을 수정합니다.

180은 초이며 3분을 말합니다. 1800을 쓰면 30분이 됩니다.session_cache_expire() 함수도 있습니다.

 

<?
session_cache_expire(1800);

//현재 페이지에만 임의로 1800을 줍니다.

session_start();

echo session_cache_expire();

//현재 설정된 세션유지 시간을 봅니다.
?>

 

session 배열 예제 0

 

※ 배열을 세션에 저장 가능하다.

 

<?

 

$arr1 = array("lee","jun");


$_SESSION["name"]=$arr1;

 

echo $_SESSION["name"];

echo $_SESSION["name"][0];
echo $_SESSION["name"][1];
echo count($_SESSION["name"]);

 

?>

 

session 예제 1

 

<?

session_start();

//처음 페이지가 로딩될 때는 $mode에 값이 없으므로 switch문은 그냥 통과된다. 
echo " >>", $mode, "<< ";
switch ($mode) 
{

// 세션_시작 
case 'register':

//세션 변수를 등록 동시에 초기화
$_SESSION["count"] = 0;
break;

case 'count': 
// 세션등록된 $count 증가 
$_SESSION["count"] = $_SESSION["count"] + 1;
break;

case 'unregister': 
// 등록된 세션변수 $count를 제거한다. 
session_unregister("count"); 
break;

case 'destroy': 
// 세션관계없이 페이지만 다시 불러온다. 
session_destroy(); 
break; 
}
?>

당신은 이 페이지를 <? echo $HTTP_SESSION_VARS['count'] ?>번째 방문하고 계십니다.<p>

<a href="index.php?mode=register">세션변수 등록</A> | 
<a href="index.php?mode=count">세션변수 증가</A> | 
<a href="index.php?mode=unregister">등록된 세션변수 제거</A> | 
<a href="index.php?mode=destroy">세션 제거
</A><p>

<table border=1> 
<tr> 
<td>세션 모듈 이름</td> 
<td><? echo session_module_name() ?></td> 
</tr> 
<tr> 
<td>세션 파일이 저장된 경로</td> 
<td><? echo session_save_path() ?></td> 
</tr> 
<tr> 
<td>현재 세션의 아이디</td> 
<td><? echo session_id() ?></td> 
</tr> 
<tr> 
<tr> 
<td>count세션변수의 등록여부</td> 
<td> 
<? 
if(session_is_registered("count")) 
echo "등록되어있습니다."; 
else 
echo "등록되어 있지 않습니다.<br>"; 
?> 
</td> 
</tr> 
</table>

 

<?
 session_start();
 
 if($login)//로그인시도
 {
  if($userid=="lee" && $userpassword=="lee")//로그인성공
  {
   session_unset($login1);
   $_SESSION["login1"] = "lee";
   echo "<script>alert('$_SESSION[login1]');</script>";
  }
 }
 else if($logout)//로그아웃
 {
  session_unset($login1);//세션삭제
 }
 
 if($_SESSION["login1"])//세션이 등록되어있어도 참
 {
?>
<table border="1">
 <tr>
  <td>현재 로그인 중입니다.<?=session_id()?></td>
 </tr>
 <tr>
  <td colspan="2"><input type="button" onClick="location.href='<?=$PHP_SELF?>?logout=1';" value="로그아웃"></td>
 </tr>
</table>
<?
 }
 else//if($_SESSION["login"])
 {
?>
<form action="<?=$PHP_SELF?>" method="post" name="lee">
<input type="hidden" name="login" value="1">
<table border="1">
 <tr>
  <td>아이디:</td>
  <td><input type="text" name="userid"></td>
 </tr>
 <tr>
  <td>패스워드:</td>
  <td><input type="text" name="userpassword"></td>
 </tr>
 <tr>
  <td colspan="2"><input type="submit" value="전송"></td>
 </tr>
</table>
</form>
<?
 }

?>

 

session 예제 2

 

<?

function OnlyMsgView($Msg)
{
 echo"<script language='javascript'>alert(\"$Msg\");</script>";
}

$_SESSION["lee1"] = "leejunsik";
$_SESSION["lee2"] = "leejunsik";
$_SESSION["lee3"] = "leejunsik";

session_unregister("lee1");
session_unregister("lee2");
session_unregister("lee3");
 
//session_destroy();
 
//session_unset("lee1");
//session_unset("lee2");
//session_unset("lee3");

if(!session_is_registered("lee1"))
{
 OnlyMsgView("No session_id_registered");
 OnlyMsgView($_SESSION["lee1"]);
}
else
{
 OnlyMsgView($_SESSION["lee1"]);
}
 
if(!isset($_SESSION["lee2"]))
{
 OnlyMsgView("No session_id_registered");
 OnlyMsgView($_SESSION["lee2"]);
}
else
{
 OnlyMsgView($_SESSION["lee2"]);
}

if(!$_SESSION["lee3"])

 OnlyMsgView("No session_id_registered");
 OnlyMsgView($_SESSION["lee3"]);
}
else
{
 OnlyMsgView($_SESSION["lee3"]);
}

?>

 

서로 다른 웹언어(ASP,JSP,PHP)을 사용하여 세션을 공유하는법

 

1. SSO 솔류션을 이용하여 스크립트 체크을통해 로그인을 사용할수 있다. 
SSO 솔류션에서 정보를 가져오면 가능하다.

 

2. 하나의 웹언어에서 쿠키를 생성하여 다른 웹언어에서 읽어들여 세션변수에 저장합니다.

※ 대신 같은 1차,2차 도메인에서만 쿠키변수에 쓰기,읽기가 가능하다.

 

www를 붙은 도메인과 붙지 않은 도메인에서 제대로 세션공유가 안일어날때

 

index.php

<?
session_start();

$_SESSION["name"]="이xx";
$_SESSION["name1"]="하하하";

?>
<a href="
http://www.skin4u.net/test1.php">www.skin4u.net</a>
<a href="
http://skin4u.net/test2.php">skin4u.net</a>

 

test1.php

<?
 session_start();
 echo $_SESSION["name"];
 echo $_SESSION["name1"];
?>

 

test2.php

<?
 session_start();
 echo $_SESSION["name"];
 echo $_SESSION["name1"];
?>

 

www.skin4u.net에서 서핑을 하다가 세션을 구울시 skin4u.net로 다시 이동하여 서핑할경우 세션이 안먹혀 에러가 나는 경우가 있다 그럴경우에는 아래와 같이 조치한다.

 

session_start(); 전에 아래 코드를 넣어준다.

 

@header('P3P: CP="NOI CURa ADMa DEVa TAIa OUR DELa BUS IND PHY ONL UNI COM NAV INT DEM PRE"');
ini_set("session.cookie_domain", ".webprogram.co.kr");

 

※ 위의 방법은 2차 도메인끼리의 세션공유이며 1차도메인끼리의 세션공유는 DB세션을 이용하는 방법이 있습니다.



출처 : http://www.zetswing.com/bbs/board.php?bo_table=PHP_LEC&wr_id=6&page=3