서버는 보통 stateless하다. 사용자가 누구인지 기억하지 않으며, 때문에 사용자는 자신이 누구인지 알리는 정보를 보낸다. 주로 사용하는 방법이 쿠키를 통하는 방법이다.
서버는 현재 상태에 대한 데이터를 쿠키의 형태로 클라이언트에게 보낸다.
클라이언트는 이를 메모리나 디스크에 저장하며, 서버로 request를 보낼 때 마다 쿠키를 같이 전송한다.
서버는 이 쿠키를 해당 클라이언트의 상태를 기억하는데 사용하며 적절한 response를 만들어낸다.
세션은 다음이 보장되어야 한다.
이를 위해 서버는 세션 데이터를 클라이언트에 보내기 전에 암호화한다.
또한 웹 브라우저는 웹 사이트에 저장될 수 있는 쿠키의 수와 크기를 제한하기 때문에 서버는 쿠키를 만들기 전에 데이터를 압축한다.
클라이언트가 웹사이트에 접속해 로그인한다.
서버는 회원 데이터베이스를 이용해 사용자를 확인한 후
세션 저장소(데이터베이스)에 회원 정보 세션을 생성한다.
생성한 세션의 Id를 클라이언트에게 보내준다.
클라이언트는 이 Id를 쿠키에 넣어 서버와 통신하며, 서버는 이 Id값으로 클라이언트가 누구인지 알 수 있다.
클라이언트가 접속을 종료하거나 로그아웃 하면 서버는 해당 세션Id를 제거한다.
쿠키만을 사용하는 것 보다 사용자 정보를 서버에 저장하기 때문에 보안상 안전하다.
하지만 결국 서버 데이터베이스에 저장하기 때문에 사용자가 많아지면 세션 확인이 느려지고 비용이 든다.
Json Web Token
session과 유사하게 사용자의 정보를 담고 있다. 하지만 session은 해당 정보를 서버에 저장하고, 이를 식별할 수 있는 정보를 클라이언트에게 전해주지만, JWT는 token안에 이를 식별할 수 있는 정보를 가지고 있다.
구조는 Cookie와 크게 다르지 않지만 서명된 토큰이라는 점이 다르다.
public key, private key를 사용하여 토큰에 서명할 경우 서버가 이 토큰이 정상적인 토큰인지 인증할 수 있다.
JWT는 3단계로 구성되어있다.
Header, Payload, Signature
이미 인증된 정보이기 때문에 인증 저장소가 필수적이지 않다.
클라이언트의 상태를 서버가 저장해 두지 않아도 된다.
signature를 암호화로 막아두었기 때문에 데이터에 대한 보완성이 늘어난다.
토큰 안에 데이터를 저장하기 때문에 데이터 전달량이 많다.
토큰이 탈취당하면 만료될 때까지 대처가 불가능하다.
따라서 JWT는 만료 시간을 짧게 가져간다. 토큰이 탈취당해도 금방 만료가 되기 때문에 최소한의 보안성을 얻을 수 있다.
하지만 그만큼 사용자가 매번 로그인 해야 하는 상황이 발생한다.
이는 Sliding token이나 Refresh token으로 해결한다.
refresh token은 서버 데이터베이스에 저장한다.