쿠키와 세션을 이해하려면, 먼저 쿠키와 세션이 쓰이는 프로토콜인 HTTP에 대해 이해해야 한다.
HTTP
HTTP는 클라이언트-서버 사이에 이루어지는 요청/응답(request/response) 프로토콜이다. 예를 들어 클라이언트(웹 브라우저)가 특정 웹 페이지에 접속할 경우 HTTP를 통해 해당 웹 페이지의 그림 정보 등을 서버에 요청하고, 서버는 이 요청에 응답하여 필요한 정보를 클라이언트에 전달하는 식이다.
HTTP는 다음 두 가지 특징을 지닌다.
- Connectionless (비연결성)
- Stateless (무상태성)
두 성질의 차이를 쉽게 이해하려면 Connectionless한 성질 때문에 Stateless 해진다 라고 생각하면 좋다.
Connectionless(비연결성)은 연결을 맺은 서버 - 클라이언트 관계에서 클라이언트의 요청에 대해 서버가 응답을 마치면 그 연결을 끊는 성질을 의미한다.
이로 인해 A 클라이언트가 보내는 5번의 요청을 서버는 모두 A 클라이언트의 요청인지, A ~ E 클라이언트가 보내는 각각의 요청인지 식별할 수 없어진다. 서버는 매 요청마다 클라이언트를 식별할 필요성이 생긴 것.
이를 클라리언트의 상태를 저장하지 않는 무상태성, 즉 Stateless한 성질 이라고 표현.
HTTP는 왜 Connectionless하고 Stateless할까?
HTTP는 인터넷 상 불특정 다수의 통신 환경을 기초로 설계되었다. 따라서 한 번 맺은 연결을 지속적으로 유지한다면 쓸데 없이 많은 자원이 소요될 것이다. 매번 연결을 맺는 편이 지속적 연결 유지에 자원을 쓰는 것보다 효율적일 것이다.
클라이언트의 상태를 기억하기 위한 수단, 쿠키와 세션
앞서 HTTP 프로토콜의 비연결성과 무상태성으 특징으로 인해 서버가 클라이언트의 상태를 기억해야 할 필요성이 있다고 언급하였다. 이를 위해 HTTP가 선택한 수단이 바로 쿠키와 세션이다.
쿠키(Cookie)
쿠키는 서버에 인증하기 위한 클라이언트의 정보를 클라이언트 단에 저장하는 값이다.
개발자 모드의 Console 탭에서 document.cookie를 입력
출력된 값을 볼 수 있다.
set-cookie는 HTTP 응답 헤더에서 서버가 클라이언트 측에 쿠키를 전송하기 위해 사용된다.
cookie는 HTTP 요청 헤더에서 이전 서버로부터 받은 set-cookie 값을 포함한 값을 클라이언트가 전송하기 위해 사용된다.
이 쯤 되면 그래서 쿠키가 언제 생기는건가? 하는 의문이 들 것이다. 아래와 같은 단계로 이해하면 쉬울 것 같다. 핵심은 HTTP의 stateless한 성질이 어떻게 보완되느냐에 있다.
- 클라이언트가 서버에게 페이지정보를 요청
- 서버는 클라이언트에 대해 쿠키 생성 후, HTTP응답 헤더에 쿠키를 포함하여 응답(HTTP response gpejdml 'set-cookie')
- 클라이언트 요청과 서버의 응답이 끝나면 HTTP의 비연결성으로 인해 연결 끊김
- 새로운 요청을 할 경우, 이전에 받은 쿠키값을 보관하고 있다가 HTTP 요청 헤더에 값을 포함하여 요청(HTTP request 헤더의 'cookie')
- 서버는 쿠키값을보고 이전에 요청을 보낸 클라이언트를 인식하여 상태를 기억하여 HTTP의 Stateless한 성질을 보완
쿠키의 장단점
쿠키의 장점
- 사용자 입장에서 별도의 인증 과정을 거치지 않고 서버가 나를 쉽게 기억하도록 할 수 있다. ID-PW를 굳이 입력하지 않아도 되는 자동완성 기능, 지난 번 읽었던 글이 다시 새로운 글에 업데이트 되지 않도록 하는 기능 등 무상태성인 HTTP에게 상태 정보를 기억하게 하는 가벼운 일에 쿠키가 쓰인다.
쿠키의 단점
- 쿠키값을 쉽게 수정이 가능하다. 텍스트로 저장되다 보니 더욱 더 따라서 악의적인 공격자에 의해 변조될 가능성도 크다. 쿠키가 서버에 나를 기억하게 하는 용도인 동시에 보안적 약점이 있다보니 쿠키에는 중요하지 않은 정보만 저장해야 할 것이다.
세션(Seesion)
세션은 쿠키와 달리 쿠키는 서버에 인증하기 위한 클라이언트의 정보를 서버 단에서 저장 및 관리하는 방식이다. 쿠키가 쿠키값을 통해 클라이언트의 상태를 기억하게 한다면, 세션은 서버가 클라이언트에 부여한 세션ID을 통해 기억하게 한다.
그런데 이 세션 ID는 사실 쿠키를 통해 관리된다.
조금 더 자세한 세션의 동작 방식.
- 클라이언트가 서버에게 페이지 정보를 요청
- 서버는 클라이언트에 대해 쿠키 생성 후, HTTP 응답 헤더에 세션 ID값이 담긴 쿠키를 포함하여 응답(HTTP response 헤더의 'set-cooke')
- 클라이언트의 요청과 서버의 응답이 끝나면 HTTP의 비연결성으로 인해 연결 끊김
- 새로운 요청을 할 경우, 이전에 받은 쿠키값을 보관(SSID, PHPSESSID 등)하고 있다가 HTTP 요청 헤더에 세션 ID 값이 담긴 쿠키를 포함하여 요청 (HTTP request 헤더의 'cookie')
- 서버는 쿠키 내 세션 ID 값을 보고 이전에 요청을 보낸 클라이언트를 인식하여 상태를 기억하여 HTTP의 Stateless한 성질을 보완
말 그대로 쿠키를 통해 세션 ID가 저장 관리되다 보니 쿠키의 작동 방식과 거의 같다. 한가지 다른 점은 단순한 쿠키값이 아니라, 쿠키 값 내 서버가 준 세션 ID에 대한 정보를 서버와 클라이언트가 주고 받으며 서버에 클라이언트를 인증하는 것이다. 세션 ID는 서버가 발급하고,관리 하기 때문이다.
세션의 장단점
세션의 장점
- 쿠키에 비해 안전이다. 세션 ID는 클라이언트에 저장된다고 해도 클라이언트의 정보 자체는 서버에 저장되어 있기 때문이다.
- 로그인 정보를 유지하여 자동 로그인 되는 기능
세션의 단점
- 쿠키에 비해 조금 느리다. 세션은 세션 ID를 주고 받은 다음 인증을 거쳐 서버에 데이터를 참조해야 하므로 속도가 비교적 느리다.
- 세션은 서버의 자원을 사용한다. 한계가 존재하는 서버 자원을 사용하므로 속도 저하나 오버헤드 등 서버에 부하를 줄 수 있다.
- 해킹에 위험성은 여전하다. 대표적으로 세션 하이재킹(Session Hi-jacking)이 있다.
세션을 사용하면 좋은데 왜 쿠키를 사용할까?
세션은 서버의 자원을 사용하기 때문에 무분별하게 만들다보면 서버의 메모리가 감당할 수 없어질 수가 있고 속도가 느려질 수 있기 때문에 쿠키가 유리한 경우가 있습니다.
쿠키와 세션의 차이
- 쿠키와 세션은 비슷한 역할을 하며, 동작원리도 비슷합니다. 그 이유는 세션도 결국 쿠키를 사용하기 때문입니다.
- 가장 큰 차이점은 사용자의 정보가 저장되는 위치입니다. 때문에 쿠키는 서버의 자원을 전혀 사용하지 않으며, 세션은 서버의 자원을 사용합니다.
- 보안 면에서 세션이 더 우수하며, 요청 속도는 쿠키가 세션보다 더 빠릅니다. 그 이유는 세션은 서버의 처리가 필요하기 때문입니다.
- 보안, 쿠키는 클라이언트 로컬에 저장되기 때문에 변질되거나 request에서 스니핑 당할 우려가 있어서 보안에 취약하지만 세션은 쿠키를 이용해서 sessionid 만 저장하고 그것으로 구분해서 서버에서 처리하기 때문에 비교적 보안성이 좋습니다.
- 라이프 사이클, 쿠키도 만료시간이 있지만 파일로 저장되기 때문에 브라우저를 종료해도 계속해서 정보가 남아 있을 수 있다. 또한 만료기간을 넉넉하게 잡아두면 쿠키삭제를 할 때 까지 유지될 수도 있습니다.
- 반면에 세션도 만료시간을 정할 수 있지만 브라우저가 종료되면 만료시간에 상관없이 삭제됩니다. 예를 들어, 크롬에서 다른 탭을 사용해도 세션을 공유됩니다. 다른 브라우저를 사용하게 되면 다른 세션을 사용할 수 있습니다.
- 속도, 쿠키에 정보가 있기 때문에 서버에 요청시 속도가 빠르고 세션은 정보가 서버에 있기 때문에 처리가 요구되어 비교적 느린 속도를 가집니다.