php 예제로 보는 http, cookie(쿠키), session(세션)에 대한 기본 개념
안녕하세요. 개발자 드리머즈입니다.
php언어로 session의 기본 개념 공부하고 자료 정리합니다.
session에 대해 인터넷에 검색을 하면.. 많은 자료가 나오지만 정확하게 이해가 가지 않아 직접 코드로 테스트해봤습니다.
session에 대해 들어가기 전에 http에 대해 간단히 알아보겠습니다.
http를 이야기할 때, 클라이언트(client)와 서버(server)라는 개념이 등장합니다.
클라이언트는 크롬, 인터넷 익스플로러 등과 같은 브라우저를 말합니다. 우리가 클라이언트(브라우저)에서 www.daum.net과 같은 주소를 입력하면, 클라이언트(브라우저)는 요청(request)메세지를 만들어 이 주소에 해당하는 서버에 보냅니다.
서버는 웹 서비스를 제공하는 회사의 컴퓨터입니다. 저는 지금 cafe24에서 웹호스팅을 구매해서 사용하고 있지만, 직접 서버 컴퓨터를 구성해 사용할 수도 있습니다. 서버는 클라이언트(브라우저)로부터 전달받은 요청(request) 메세지를 전달받고 응답(response) 메세지를 다시 클라이언트에게 보냅니다. 서버는 클라이언트로부터 전달받은 요청 메세지에 따라 다른 응답 메세지를 보낼 수 있습니다.
다음으로 쿠키(cookie)와 세션(session)에 대해 보겠습니다.
브라우저를 많이 사용해보신 분이면 쿠키에 대해서 들어보신 적이 있을 겁니다. 무엇인지는 잘 몰라도 브라우저의 쿠키를 삭제해버리면, 이미 로그인 된 사이트였을 지라도 로그인이 해제되고.. 무슨 저장 값들이 사라지는 것을 경험해보셨을 겁니다. 쿠키는 브라우저의 특정 데이터가 저장되는 공간입니다.
크롬에서 이를 확인하기 위해서는
위의 그림에 나탄나 것처럼 1번, 2번, 3번을 클릭하여 개발자 도구를 켜야합니다.
그리고 나타난 개발자 모드에서 1번, 2번을 클릭한 후 확인을 원하는 도메인(주소)를 클릭(3번)하면 4번의 화면에
쿠키를 볼 수 있습니다.
이 쿠키 데이터는 (GET, POST와 같은 다른 데이터와 더불어..) 서버로 보내지는 request message에 포함됩니다.
이를 실제로 확인하기 위해서는
개발자 모드에서 위의 그림에 나타난 1번을 눌러 Nework 탭으로 가고, 2번을 눌러 Clear한 다음에, 3번을 눌러 특정 사이트를 새로고침 하면, 4번의 영역에서 새로고침 하면서 서버와 주고받은 http message들을 볼 수 있습니다.
위의 그림과 같이 주소 값을 하나 선택하면(1번), 2번의 Header 탭에서 3번의 Request Header와 4번의 Response Header를 볼 수 있습니다. (Response Header 영역이 위에 있지만, 순서 상으로 Request Header가 먼저 발생하고 그 다음에 이에 대한 Response Header가 발생함)
Request Header의 cookie를 포함하여 여러 값들이 서버로 전달되고, 서버는 이 값들을 다 볼 수 있습니다.
(마찬가지로 Response Header의 여러 값들은 클라이언트로 전달되고, 클라이언트는 이 값들을 다 볼 수 있음)
서버는 요청 메세지의 쿠키 데이터를 보고, 이에 따라 다른 response message를 브라우저로 보낼 수 있습니다. 결국 우리가 브라우저에서 보게되는 화면이 달라지게 됩니다.
그리고 Response Header에 set-cookie라는 속성이 있습니다. 클라이언트(브라우저)는 수신한 Response Header에 set-cookie가 있다면, 여기에 있는 키=벨류 쌍들을 클라이언트의 쿠키에 저장(갱신)합니다. 이 과정을 통해 클라이언트의 cookie 값이 갱신됩니다.
세션은 쿠키와 밀접한 관련이 있습니다. 세션은 사용자의 로그인과 같은 민감한 상태를 인식하는데 사용됩니다.
세션을 이해하기 위해서는 세션 쿠키, 세션 ID(session id또는 SID), 세션 이름(session name), 세션 파일, 세션 변수를 알아야 합니다.
먼저 세션 쿠키에 대해 보겠습니다.
좀 전에 본, 크롬 개발자 모드의 Application 영역의 Cookie 값들을 다시 가져왔습니다. 여기에 자세히 보면, Expires
/Max-Age칸에 날짜가 적혀있는 쿠키(Persistent Cookie, 영구적 쿠키)가 있고, Session이라고 적힌 쿠키(Session Cookie, 세션 쿠키)도 있습니다. 영구적 쿠키는 그 값들이 메모리가 아닌 디스크에 저장되며 만료일(Expires)에 도달하면 삭제됩니다. 이와 달리 만료일에 지정된 값이 없으면 세션 쿠키로 취급되며, 세션 쿠키는 디스크가 아닌 메모리에 그 값이 저장되어 브라우저를 종료하면 사라집니다.
쿠키에 여러 Name이 있듯이 Session도 여러 Name을 가질 수 있습니다. 클라이언트(브라우저)쪽에서 본다면, 세션 쿠키의 이름이 session name입니다. 이 쿠키의 value는 session id라고 부릅니다.
쿠키가 클라이언트에 저장되는 반면, 세션은 서버에 파일로 저장되는데 이 파일을 세션 파일이라고 부릅니다.
세션 변수는 서버 쪽에서만 사용되는 개념으로 세션 변수을 통해 세션 파일 내부의 값에 접근합니다.
기본적인 개념 설명만으로는 이해가 어렵기 때문에,
세션이 서버와 클라이언트에서 어떻게 동작하는지 알아보기 위해 php 예제로 실험해보겠습니다.
session_test.php(예제1)
<?php session_save_path("./session/"); |
아주 간단한 파일입니다. 이 파일을 서버에 올리고 접속한 결과는 아래와 같습니다.
클라이언트가 보낸 Request 메세지를 서버가 수신하면, 서버의 session_test.php코드가 차례대로 실행됩니다.
①session_save_path()함수는 서버 내의 세션 파일이 저장될 위치를 지정합니다. 이 함수가 호출되지 않으면 php.ini에 명시된 default 경로에 저장됩니다.
session_start()함수는 세션 작업을 시작하는 함수입니다. 하는 일은 아래와 같습니다.
②먼저 자신의 session name을 파악합니다. PHP에서 기본 session name이 PHPSESSID입니다. (만약 다른 세션 이름을 사용하고 싶다면 session_name("MYSESSID"); 를 이용해 원하는 세션명으로 변경 가능함)
③Request Header의 Cookie에서 session name을 key로 가지는 쿠키가 있는지 확인합니다. 위의 사진에서 보면 Request Header에 Cookie 속성이 아예 없습니다. 왜냐하면 이 Domain(주소)로는 처음 접속하기에 이 Domain에 사용될 Cookie는 아직 서버로부터 받지 못했기 때문입니다.
④서버(session_test.php)는 Request Header에 자신의 session name을 key로 가지는 쿠키가 없기 때문에, 새로운 세션을 시작해야 한다고 판단합니다. 랜덤 문자열인 session id를 생성(위의 예제에는 ar3jlkcnpgdke5pt6ttrs8kbg6)합니다. 동시에 서버 내의 세션 파일을 생성합니다.
(Request Header에 session name을 키로 가지는 쿠기가 없으면 session id를 생성함)
실제로 서버에 가서 확인해보면 생성된 session id에 접미사 sess_가 붙은 파일이 생성된 것을 확인할 수 있습니다.
⑤서버(session_test.php)는 Response Header의 Set-Cookie에 session name을 key로, session id를 value로 하는 쿠키를 담아 클라이언트(브라우저)에게 보냅니다.
⑥클라이언트는 서버로부터 전달받은 Response Header의 Set-Cookie에 있는 쿠키를 자신의 쿠키에 저장합니다.
이제 클라이언트의 쿠키는 서버의 세션 이름과 세션 id를 가지고 있습니다.
이 상태에서 아래의 파일이 있는 주소로 접속을 하면,
session_test_set.php(예제2)
<?php session_save_path("./session/"); echo " \$_SESSION['userId'] = 10000"; |
위와 같은 결과를 얻습니다.
이전의 테스트 덕분에 이번에는 Request Header에 session_test_set.php가 사용하는 세션 이름의 쿠키가 있습니다. 따라서 서버(session_test_set.php)는 클라이언트와 이미 세션이 연결이 이루어졌다고 판단하고, 이전과 달리 Response Header의 Set-Cookie 작업을 하지 않았습니다.(클라이언트가 새로 세션 쿠키를 저장할 필요가 없음)
그리고 이번 예제에 서버쪽 에서만 사용하는 세션 변수에 접근하는 부분이 있습니다. PHP에서는 $_SESSION가 바로 세션 변수입니다.
$_SESSION['userId'] = 10000;
$_SESSION['userName'] = "Dreamaz";
위의 두 코드처럼 세션 변수에 접근하여 값을 할당하면 이 내용이 세션 파일에 저장됩니다.
위와 같은 형태로 저장됩니다.
파일에 저장되기 때문에 다른 php파일에서도 접근할 수 있습니다.
아래와 같이 작성된 코드에 접속을 하면
session_test_get.php(예제3)
<?php |
위와 같은 결과를 얻습니다. 세션 변수에 접근하여 저장된 파일의 값을 읽어옵니다.
예제에서는 간단히 하기 위해, 세션 변수에 동일한 userId와 userName을 입력했습니다. 하지만 실제 서버에서는 session id로 구별되는 세션에 따라서(세션은 각각의 사용자마다 다르므로, 결국 사용자에 따라) 다른 세션 변수 값들을 할당하여 사용할 것입니다.
sess_aaaaa 의 userId는 12345, userName은 Hong,
sess_bbbb 의 userId는 50000, userName은 Lee
처럼 말입니다.
지금은 클라이언트(브라우저)에 세션 쿠키가 저장되어 있지만, 만약 일부러 쿠키를 삭제하고
(혹은 모든 크롬 브라우저를 종료한 후에) 서버에 접속한다면 어떻게 될까요?
그렇다면 서버는 클라이언트와 세션이 처음 이루어진다고 생각하고 예제1과 같이 새로운 세션을 발생할 것입니다.
그런데 쿠키만 사용하여 사용자를 구별할 수 있지 않느냐라고 생각하실 수 있습니다. 예를 들어 아래와 같은 정보를 쿠키로 주고 받으면 안되냐는 의견이죠.
key |
value |
userId |
12345 |
userName |
Hong |
하지만 쿠키는 손쉽게 조작이 가능한 영역입니다. 브라우저에서는 브라우저가 알아서 쿠키 값들을 작성해서 서버로 보내기에 우리가 임의로 수정할 수 없지만, curl등과 같은 프로그램을 사용하면 우리가 쿠키를 지정할 수 있습니다. 그렇다는 말은 마음만 먹으면 손쉽게 userId와 userName을 변경할 수 있다는 말이죠.
그래서 보안상의 이유로 클라이언트와 서버는 랜덤 문자열인 session id를 서로 주고 받아 세션을 구별하며, 중요한 정보는 클라이언트 쪽이 아닌 서버 쪽의 세션 파일 내부에 저장하여 사용합니다.
여기까지 php 예제로 보는 http, cookie, session에 대한 기본 개념 설명이었습니다.
*참고
쿠키 설명(위키피디아) : https://en.wikipedia.org/wiki/HTTP_cookie#Session_cookie
댓글 영역