🍪⏳🪙
쿠키, 세션, 토큰은 모두 데이터를 저장하는 개념이다. 소프트웨어에서 불필요하게 반복되는 작업은 줄이는 것이 좋다. 웹 사이트에 방문했을 때 사용되는 로그인 정보처럼, 자주 사용되는 정보는 반복적으로 작업하지 않도록 저장해 두는 것이 효율적이다.
이렇게 웹 환경에서 반복적으로 사용되는 데이터나 정보를 저장하고 재활용하는 방식은 다양하게 존재하는데, 그중 대표적인 것이 바로 쿠키 / 세션 / 토큰이다. 이들이 어떠한 방식으로 사용되는지, 그 특징과 차이점은 무엇인지 알아보자! :>
웹서핑을 하면서 어떤 사이트에 들어가면 쿠키를 설정하라는 문구를 본 적이 있을 것이다. 이 쿠키 때문에 쇼핑 사이트에 로그인하지 않아도 장바구니에 물건을 담아두거나 검색 기록에서 이전에 입력했던 검색어들을 찾아볼 수 있다. 나의 웹 서핑 내역이 마케팅과 광고에 활용되는 것도 쿠키를 통해 이뤄지는 일이다.
쿠키는 크롬이나 사파리 같은 브라우저에 저장되는 작은 텍스트 조각이다. 브라우저는 사용자의 컴퓨터에 설치된 소프트웨어이므로 쿠키는 사용자가 갖고 있는 정보라고 할 수 있는 것이다.
사용자는 브라우저의 설정 화면이나 개발자 도구에서 쿠키를 확인하고 수정, 삭제할 수 있다. 다만 쿠키는 당사자뿐만 아니라 제3자가 조회하는 것도 가능하기 때문에 개인 정보를 담은 내용이나 보안상 민감한 정보를 저장하는 데에는 적합하지 않다. 따라서 혹여 남에게 탈취되거나 사용자에 의해 조작되어도 크게 문제 되지 않을 정보를 브라우저에 저장함으로써 웹사이트 이용을 편리하게 해 주는 것이 쿠키이다. 예를 들면 쇼핑몰의 검색 내역이나 웹 페이지의 다크 모드 설정 여부 등과 같은 간단한 정보 말이다.
"로그인 여부 등 사용자와 서버의 관계가 기억되어 보존되고 있는 상태"
웹사이트에 아이디와 비밀번호를 입력해서 로그인하면 해당 사이트의 회원에게만 허용된 기능들을 사용할 수 있다. 마이페이지를 클릭해서 내 정보를 볼 수도 있고, 회원 전용 게시판의 글쓰기 버튼을 클릭해서 질문을 남기거나 리뷰를 쓸 수도 있다.
문제는 아이디와 비밀번호를 입력해 로그인에 성공한 사용자와 로그인한 다음 마이페이지 버튼을 누른 사용자가 동일 인물임을 알지 못한다는 것이다.
프로토콜의 이러한 특성을 다음과 같이 표현한다.
- Connectionless 프로토콜 (비연결)
: 클라이언트가 서버에 요청을 했을 때, 요청에 맞는 응답을 보낸 후 연결을 끊는 처리 방식- Stateless 프로토콜 (무상태)
: 클라이언트의 상태 정보를 가지지 않는 서버 처리 방식. 클라이언트와 첫 번째 통신에 데이터를 주고받았다 해도, 두 번째 통신에 이전 데이터를 유지하지 않음
이러한 특성 때문에, 사용자가 사이트에 로그인한 상태라는 점을 서버에 인증하지 못하면 클릭을 할 때마다 반복해서 아이디와 비밀번호를 서버에 제공해야 한다. 이런 번거로움을 해결하기 위해 등장한 것이 바로 세션이다.
사실 사용자의 로그인 상태를 유지하는 기능을 위해 쿠키에 아이디와 비밀번호를 담아두고 있을 수도 있다. 그러나 이 방법의 문제점은, 개인 소유가 아닌 컴퓨터에서 사용할 경우 사용자의 개인정보가 위험해진다는 것이다. 그래서 로그인의 내용은 세션 파트에서 논한다.
세션은 사용자가 이미 서버로부터 인증받았음을 증명해 주는 증서이다. 세션은 사용자가 사이트에 한 번 로그인하면 유효기간이 끝날 때까지 더 이상 아이디와 비밀번호를 입력하지 않아도 되도록 해준다.
사용자가 서버에 올바른 아이디와 비밀번호로 로그인에 성공하면 서버는 세션 아이디라는 데이터를 만든다. 보통은 ‘2sd98dbawix4’와 같은 식으로 알파벳과 숫자가 혼합된 형식을 갖고 있다. 서버는 영화관에서 티켓을 보관용 부분만 찢어 건네주듯 세션 아이디를 사용자에게 전달하고, 메모리에 아이디 사본을 어떤 사용자의 것인지 적어서 보관한다.
이를 편지에 비유해 보자. 사용자는 서버로부터 받은 세션 아이디를 쿠키로 저장한 다음 앞으로의 모든 요청에 함께 전달한다. 친구 목록을 볼 때, 댓글을 작성하거나 삭제할 때, 구매한 상품 내역을 볼 때도 서버에게 세션 아이디를 적은 편지를 보낸다.
서버는 사용자에게서 친구 목록을 보겠다는 요청을 받으면 그 편지에 세션 아이디가 적혀있는지를 확인한다. 아이디가 있다면 서버가 보관하고 있는 세션 아이디 중에 동일한 정보가 있는지 찾아보고 그것이 누구의 계정인지도 알아낸다. 그렇게 편지를 보낸 사람이 누구인지 파악한 다음 해당 사용자의 친구 목록을 보내주는 것이다.
그러나 세션 방식은 안전하고 효과적이지만 단점도 있다. 서버는 요청마다 함께 딸려 오는 세션 아이디를 바로바로 확인할 수 있도록 로그인한 사용자의 아이디를 메모리라는 ‘책상’에 올려둔다. 이는 메모리에 올려둔 데이터를 빠르게 확인할 수 있다는 장점이 있는 대신 공간이 한정되어 있다. 서버에 동시 접속하는 사용자가 많아지면 메모리 공간이 부족해져서 서버에 부하가 걸릴 수 있는 것이다. 이러한 서버 부하 문제를 해결하기 위해 등장한 것이 바로 토큰이다. 아래에서 그 원리를 알아보자.
메모리 공간을 많이 차지하는 세션 방식의 대안은 로그인한 사용자에게 세션 아이디 대신 토큰을 발급해 주는 것이다. 이러한 토큰에는 특수한 수학적 원리가 적용되어 있어서 마치 위조 방지 장치가 있는 지폐처럼 서버만이 유효한 토큰을 발행할 수 있다.
그렇기 때문에 토큰을 받아 간 사용자가 이를 쿠키로 저장해 두고 필요할 때마다 제시하면 서버는 따로 책상에 올려놓은 것을 확인할 필요 없이 자기가 발급한 토큰임을 알아보고 사용자의 요청을 허가해 주는 것이다. 더 이상 이미 로그인한 사용자의 티켓을 책상(메모리)에 올려 두고 있을 필요가 없으니 서버 부하를 줄일 수 있다.
물론 토큰 방식에도 한계는 있다. 한 번 발행한 토큰은 유효기간이 끝나기 전까지 따로 통제할 수 없기 때문에 세션에 비해 토큰 정보를 탈취 당할 가능성이 높다. 그러나 토큰은 쿠키처럼 만료 기간을 정할 수 있어서 만료 시간을 짧게 지정해 피해를 줄일 수 있다.
세션의 경우 Cookie 헤더에 세션 ID만 실어 보내면 되므로 트래픽의 규모가 작다. 하지만 JWT는 사용자 인증 정보와 토큰의 발급 시각, 만료 시각, 토큰의 ID 등 담겨있는 정보가 세션 ID에 비해 비대하므로 세션 방식보다 훨씬 더 많은 네트워크 트래픽을 가진다.
(+) 트래픽(traffic) : 일정 시간 내에 흐르는 데이터의 양
세션의 경우 모든 인증 정보를 서버에서 관리하기 때문에 보안 측면에서 조금 더 유리하다. 설령 세션 ID가 해커에게 탈취된다고 하더라도, 서버 측에서 해당 세션을 무효 처리하면 된다.
하지만 토큰의 경우 그렇지 않다. 토큰은 서버가 트래킹 하지 않고, 클라이언트가 모든 인증정보를 가지고 있다. 따라서 토큰이 한번 해커에게 탈취되면 해당 토큰이 만료되기 전까지는 속수무책으로 피해를 입을 수밖에 없다.
또한 JWT 특성상 토큰에 실린 Payload가 별도로 암호화되어있지 않으므로, 누구나 내용을 확인할 수 있다. 따라서 Payload에 민감한 데이터는 실을 수 없다. 즉, Payload에 실을 수 있는 데이터가 제한된다.
하지만 세션과 같은 경우에는 모든 데이터가 서버에 저장되기 때문에 아무나 함부로 열람할 수 없으므로 저장할 수 있는 데이터에 제한이 없다.
그럼에도 불구하고 최근에 토큰 기반 인증을 많이 사용하는 이유가 바로 이 확장성에 있다.
일반적으로 서버 확장 방식은 수평 확장을 사용한다. 즉, 한 대가 아닌 여러 대의 서버가 요청을 처리하게 된다. 이때 별도의 작업을 해주지 않는다면, 세션 기반 인증 방식은 세션 불일치 문제를 겪게 되기에 별도의 작업을 해주어야 하는 번거로움이 있다.
하지만, 토큰 기반 인증 방식의 경우 서버가 직접 인증 방식을 저장하지 않고, 클라이언트가 저장하는 방식을 취하기 때문에 이런 세션 불일치 문제로부터 자유롭다. 이런 특징으로 토큰 기반 인증 방식은 HTTP의 비상태성(Stateless)을 그대로 활용할 수 있고, 따라서 높은 확장성을 가질 수 있다.
확장성과 어느 정도 이어지는 내용이다. 세션 기반 인증 방식은 서비스가 세션 데이터를 직접 저장하고, 관리한다. 따라서 세션 데이터의 양이 많아지면 많아질수록 서버의 부담이 증가할 것이다.
하지만 토근 기반 인증 방식은 서버가 인증 데이터를 가지고 있는 대신, 클라이언트가 인증 데이터를 직접 가지고 있다. 따라서 유저의 수가 얼마나 되든 서버의 부담이 증가하지 않는다.
📝 정리하기
쿠키는 브라우저에 저장되는 단순한 정보, 세션은 서버에게 확인받기 위한 인증서, 토큰은 그 자체로 권한(인증 정보)을 가지는 인증서라고 할 수 있겠다.