위의 세 단어 중 쿠키와 세션은 인터넷 생활을 하는 현 시대에서 자주 들어봤을 단어들이다. 쿠키가 존재하기에 로컬에 내 로그인 정보가 저장되고 세션이 존재하기에 내 로그인 정보가 서버에 저장된다는 사실은 웹서핑을 하다 보니 알게되었다. 하지만 이런 것들이 자세히 무엇인지, 또한 Token이란 무엇인지.. 제대로 배운 적이 없었다. 이번 글을 통해 세 가지를 자세히 알아볼 것이다.
예전에 HTTP에 대해 썼던 것을 되돌아보면 HTTP 통신은 무상태 프로토콜로 그때 그때 연결을 하고(Connectionless), 통신 시 필요한 데이터를 넘기지만 이후 이런 연결상태를 남기지 않는다(Stateless).
그렇다면 사용자는 HTTP 통신에 자신에 대한 정보를 줄 필요가 있다.
이때 이 ‘정보’ 역할을 할 수 있는 것들이 쿠키, 세션, 토큰이 된다.
→ 쿠키/세션/토큰: 내가 누군지에 대한 정보를 저장해서 서버에 넘겨주기 위해 필요한 것
HTTP의 일종으로 사용자가 어떠한 웹 사이트를 방문할 경우, 서버에서 사용자의 브라우저에 저장하는 작은 기록 정보 파일이다.
조금 더 자세히 말하자면 key-value로 묶여있는 데이터 조각들로 브라우저에서 해당 브라우저가 방문한 웹사이트와 웹사이트 별 필요한 정보를 저장해 둔 파일이다.

이때, 서버는 쿠키에 담긴 정보를 바탕으로 해당 요청의 클라이언트가 누군지 식별할 수 있다.
위에서 보듯 쿠키는 결국 쌓이는 리소스들이기 때문에 생성되고 삭제된다. 이런 생명 주기는 크게 2가지가 있다.
위의 단점에서 보이듯 쿠키를 이용한 데이터 기록은 개인정보 유출의 위험이라는 보안상 이슈가 존재한다. 이런 점을 해결하기 위해 나온 기술이 Session이다.
비밀번호 등 클라이언트의 민감한 인증 정보를 브라우저가 아닌 서버측에서 저장하고 관리할 수 있도록 클라이언트에서 서버로 가는 요청이 이전 상태를 유지하기 위해 사용하는 기술.
Session은 또한 클라이이언트가 웹서버에 연결된 순간부터 웹 브라우저를 닫아 서버와의 통신을 끝낼 때 까지의 기간 이다.
서버에 Session에 대한 정보(Session 상태, Session 데이터 등)를 저장해 놓고, 고유한 세션 ID를 쿠키에 저장해 클라이언트에 보내준다.
쿠키로만 인증수단을 가지면, 쿠키를 열어보면 누가 로그인했는지 알 수 있고, 데이터 조작도 가능하다.
→ 따라서 직접적인 정보들을 암호화한 값이 세션이다. 중요한 정보는 서버에 저장하고,접근할 수 있는 세션키 값만 브라우저에 저장한다.

클라이언트가 서버에 요청을 보낸다.
서버는 클라이언트별 세션을 생성해 서버 메모리에 저장한다.
세션 식별키인 Session id 를 기준으로 정보를 저장한다.
Session id를 Cookie에 담아 클라이언트에게 전달한다.
이는 브라우저에 저장되며 브라우저 종료 시에 사라진다.
클라이언트는 재요청 시에 쿠키에 Session id를 담아 전송한다.
서버는 받은 Session id로 세션을 식별해 응답한다.
위의 Session과 Cookie를 쓰면 다 되는 것 같지만 사실 그렇지는 않다. Session의 특징에서 적었듯 서버 부하의 문제가 아직 남았기 때문이다. 이를 해결하기 위해 등장한 것이 Token방식이다.
사용자 인증으로 접근 권한을 부여하는 암호화된 문자열을 말한다.
Session은 결국 토큰과 마찬가지로 세션 id를 주고받아야 한다. 이 과정에서 부하가 발생하는 것인데 Token은 암호화된 문자열로 이 서버만의 유효한 Token 발행이 가능하다. 이 Token을 Cookie에 저장하고 요청 시 Token을 전송하면 따로 주고 받을 필요 없이 Token의 복호화 만으로 해당 서버에서 발급된 것인지 판단 가능해진다. 이로 인해 정보를 주고 받는 단계가 줄어들 수 있어 부하가 감소한다.

클라이언트가 서버에 요청을 보낸다.
서버는 해당 계정 정보를 검증한 후 클라이언트에게 signed token을 발급한다.
signed 란? 해당 토큰이 서버에서 정상적으로 발급된 토큰임을 증명하는 signature을 지니고 있다.
클라이언트는 전달받은 토큰을 저장해 두고, 서버에 요청할 때마다 헤더에 해당 토큰을 함께 전달한다.
서버는 토큰을 검증하고, 요청 데이터에 대한 응답을 보낸다
Token 방식 중 가장 많이 사용되는 것이 JWT로 JSON 포멧으로 저장하는 web Token이다.
짧은 만료 기한 설정
토큰의 만료 시간이 짧으면 탈취되더라도 금방 만료되기 때문에 피해를 최소화 할 수 있다. 하지만 사용자가 자주 로그인 해야 하는 불편함이 있다.
Sliding Session
서비스를 지속적으로 이용하는 클라이언트에게 자동으로 토큰 만료 기한을 늘려주는 방법으로, 1번의 단점을 보완해줄 수 있는 전략이다. 이는 곧 로그인을 하지 않아도 항상 유지가 되므로 보안상 취약점이 생길 수 있다.
Refresh Token
위에서 인증에 사용되는 Token을 Access Token 이라고 하고 그보다 만료 기간이 긴 Refresh Token을 따로 생성해 같이 내려준다. 클라이언트는 Access Token이 만료되었을 때, Refresh Token을 사용하여 Acess Token의 재발급을 요청할 수 있다. 서버는 DB에 저장된 Refresh Token과 비교하여 유효한 경우 새로운 Access Token을 발급하고, 만료된 경우 다시 로그인 하도록 한다. 이렇게 한다면 1번과 2번의 문제를 한번에 해결할 수 있지만 검증을 위해서는 서버에 Refresh Token을 별도로 저장 시켜야 하기에 JWT의 Stateless의 장점이 없어지게 되고 구조적 구현 과정이 복잡해진다.
Cookie: 브라우저에 간단한 정보를 기억할 수 있게 하는 도구이다.
Sessio: Cookie의 보안적 취약점을 해결하기 위해 서버에 Cookie에 관한 정보를 넘겨서 관리하는 인증 방법이다.
Token은 Session의 인증 방법을 간략화하기 위해 암호화된 문자열을 사용하는 방식이다.