여기서는 HTTP 통신의 무상태성(stateless)를 지원하기 위해 사용되는 쿠키와 세션에 대해서 알아볼 것입니다.
또한, 이것이 취약점으로 이어질 수 있는 가능성에 대해서도 이야기 해볼 것입니다.
먼저 쿠키와 세션의 필요성에 대해서 이해하기 위해 웹 통신에서 사용되는 통신 프로토콜인 HTTP에 대해서 간단히 언급하고 가겠습니다.
일반적으로 웹 통신은 HTTP 프로토콜을 사용합니다.
HTTP 프로토콜의 주요 특징 중 하나는 무상태성(stateless)으로 클라이언트-서버 간에 메시지를 전달해주는 작업을 수행하지만, 그에 관련된 연결 정보는 어느 서버에도 저장해놓고 있지 않는다는 의미입니다.
따라서, HTTP 프로토콜이 원할하게 수행되기 위해서 헤더에 필요한 부가적인 정보(메타데이터)를 담는 것입니다.
그렇다면 사용자가 웹에 접속하여서 특정 웹사이트에서 로그인을 하려고 한다고 가정해봅시다.
사용자는 다음과 같은 절차를 수행할 것입니다.
앞서 말했지만 HTTP 프로토콜은 무상태성이기 때문에 주고 받는 정보에 관련하여 별다른 조치(저장)을 취하지 않습니다.
이것은 요청들이 각각 "독립적"으로 수행된다는 것을 의미합니다.
따라서, 4번의 동작을 통해 클라이언트에게 권한을 부여한다고 해도 이후에 보내는 요청은 독립적으로 수행되기 때문에 브라우저에 해당 정보를 단순히 저장한다고 해도 서버는 해당 정보를 이용할 수 없습니다.
여기서 고려해볼 수 있는 점은 로컬 스토리지를 이용해서 검사를 한 후 로컬 스토리지에 사용자 관련 정보가 저장되어 있다면 보내고, 없다면 안보냄으로써 사용자에 대한 권한을 검증할 수 있습니다.
하지만, 이와 같은 방식으로 구현을 할 경우 다음과 같은 취약점을 가지게 됩니다.
추가적으로 인증이 필요한 요청이 필요할 때마다 로컬 스토리지를 확인해서 담아주는 작업을 수행하는 것은 반복적인 작업이 될 것입니다.
이외에도 쿠키를 사용해야 되는 목적들에는 다음과 같은 것들이 있습니다.
쿠키는 웹사이트가 사용자의 컴퓨터나 모바일 기기에 저장하는 작은 데이터 조각입니다. 웹사이트는 쿠키를 사용하여 사용자의 선호도, 로그인 상태, 쇼핑 카트 내용 등을 기억합니다.
특징은 다음과 같습니다.
특징
5번에서도 설명되어 있듯이, 쿠키는 보안상 취약점이 될 수 있습니다.
또한 3번의 설명과 같이 브라우저는 쿠키를 자동 전송해주는 기능을 가지고 있기 때문에 SSL/TLS와 같은 프로토콜을 사용해야 되는 것을 "강요"합니다.
따라서, 쿠키에 넣어야 되는 정보들은 노출되어도 크게 문제되지 않을 정보들을 넣는 것을 선호합니다.
실제로 스크립트를 통해서 브라우저에 저장되는 쿠키를 create
, delete
, read
할 수 있기 때문에 조심해야 합니다.
그렇다면 위에서 언급했던 사용자 정보는 어떻게 관리해야 하는 것일까요?
사용자 정보를 쿠키에 그대로 넣는 것은 위험해 보입니다. 그래서 "세션"이라는 개념을 통해서 우리는 사용자의 로그인 상태를 유지할 수 있도록 도와줍니다.
세션은 사용자가 웹사이트를 방문하는 동안 일시적으로 서버에 저장되는 데이터입니다. 세션은 사용자가 브라우저를 열고 닫을 때 생성되고 삭제되는 일련의 상호작용을 말합니다.
다음과 같은 특징들을 가지고 있습니다.
세션은 쿠키와 서버의 조합으로 이루어집니다.
쿠키에 고유한 세션 ID를 담아서 클라이언트 측에 저장하게 하고, 서버는 그 고유한 세션 ID를 이용해서 사용자와 관련하여 필요로 하는 정보를 저장하고 있는 것으로 동작합니다.
즉, 정리하자면 쿠키에는 노출이 되어도 되지만 사용자의 편의를 위해 사용되어야 하는 정보들을 저장하며 세션에는 노출이 되면 안되는 정보들을 이용해야 하는 상황에서 사용해야 합니다.
이후 다른 페이지에서 정리를 할테지만, 세션을 사용해서 로그인 방식을 구현하는 것에는 한계가 있습니다.
현재 인터넷은 이전보다 훨씬 스케일이 커졌으며, 그것을 견뎌내기 위해서 여러 형태의 아키텍처들이 많이 나오고 있습니다. 그 중 확장성과 유연성을 제공하는 마이크로서비스 아키텍처(MSA)는 많은 애플리케이션에서 채택되어 사용되고 있는 아키텍처 중 하나입니다.
MSA의 주요 이점 중 하나인 유연한 Scale Out
은 하나의 서버에서 많은 요청을 견뎌내기 힘들 때 서버의 성능을 올리는 것이 아닌 인스턴스를 추가함으로써 부하 분산을 통해 요청을 처리하는 기법을 의미합니다.
앞에서 언급했던 것처럼 세션은 쿠키의 기능을 이용하여 사용자 정보를 별도의 서버에 저장한다고 했습니다.
만약, 로그인을 수행할 수 있는 서버가 여러 개라면 어떻게 될까요? 로그인을 수행한 서버와 서비스(동작)를 제공해주는 서버가 별도로 존재하면 어떻게 되는 것일까요?
분명 로그인을 했는데도 불구하고 로그인 검증이 실패하는 상황이 발생할 수 있으며 로그인을 수행한 서버와 서비스 서버가 별도로 존재하기 때문에 세션 데이터를 사용하기 쉽지 않을 수 있습니다.
이를 위해서 우리는 Token과 Sticky Session이라는 기법에 대해서 알아볼 필요가 있습니다. 다른 페이지에서 다루겠습니다.