Cookie vs Session vs Token
쿠키 기반 자격 증명 방식
쿠키는 크롬이나 사파리 같은 브라우저에 저장되는 작은 텍스트 조각입니다.
브라우저는 사용자의 컴퓨터에 설치된 소프트웨어이므로 쿠키는 사용자가 갖고 있는 정보라고 할 수 있습니다.
사용자는 브라우저의 설정 화면이나 개발자 도구에서 쿠키를 확인하고 수정, 삭제할 수 있습니다
쿠키는 당사자뿐만 아니라 제 3자가 조회하는 것도 가능하기 때문에 개인 정보를 담은 내용이나 보안상 민감한 정보를 저장하는 데에는 적합하지 않습니다.
남에게 탈취되거나 사용자에 의해 조작되어도 크게 문제되지 않을 정보를 브라우저에 저장함으로써 웹사이트 이용을 편리하게 해줍니다.
✅ 쿠키 기반 자격 증명의 특징
-쿠키는 클라이언트 측에 저장되기 때문에 안전하지 않은 환경에서는 쿠키가 탈취되어 보안 위험이 발생할 수 있습니다.
-세션을 관리함으로써 사용자의 활동을 트래킹하고 세션 동안 지속적으로 인증을 유지할 수 있습니다.
-쿠키를 통해 세션의 유지 기간을 조절할 수 있습니다. 보안 정책에 따라 세션의 유지 기간을 설정할 수 있습니다.
===========================================================================
HTTP 프로토콜은
request를 전송한 후, response를 수신하게 되면 연결을 끊는 비 연결성(Connectionless)의 특성,
request와 response에 대한 상태를 저장하지 않는 비 상태성(Stateless)의 특성이 있기 때문에
로그인 인증이 성공적으로 수행되었다 하더라도 서버 측에서는 매번 request를 수신할 때마다
이 request가 인증된 사용자가 보낸 request인지 알 방법이 없습니다.
이러한 HTTP 특성으로 인해 사용자의 인증이 성공적으로 이루어졌을 때,
인증된 사용자 request의 상태를 유지하기 위한 수단이 필요하게 되었으며
대표적인 수단이 바로 세션입니다.
===========================================================================
세션 기반 자격 증명 방식
세션기반 인가는 사용자의 인증 정보가 서버의 세션 저장소에 저장되는 방식입니다.
사용자가 로그인을 하면, 해당 인증 정보를 서버의 세션 저장소에 저장하고,
사용자에게는 저장된 세션 정보의 식별자인 Session ID를 발급합니다.
발급된 Session ID는 브라우저에 쿠키 형태로 저장되지만, 실제 인증 정보는 서버에 저장되어 있습니다.
브라우저는 인증 절차를 마친 이후의 요청마다 HTTP Cookie 헤더에 Session ID 를 함께 서버로 전송합니다.
서버는 요청을 전달받고, Session ID에 해당하는 세션 정보가 세션 저장소에 존재한다면
해당 사용자를 인증된 사용자로 판단합니다.
✅ 세션 기반 자격 증명의 특징
- 세션은 인증된 사용자 정보를 서버 측 세션 저장소에서 관리합니다.
- 생성된 사용자 세션의 고유 ID인 세션 ID는 클라이언트의 쿠키에 저장되어 request 전송 시, 인증된 사용자인지를 증명하는 수단으로 사용됩니다.
- 세션 ID만 클라이언트 쪽에서 사용하므로 상대적으로 적은 네트워크 트래픽을 사용합니다.
- 서버 측에서 세션 정보를 관리하므로 보안성 측면에서 조금 더 유리합니다.
- 서버의 확장성 면에서는 세션 불일치 문제가 발생할 가능성이 높습니다.
- 세션 데이터가 많아질수록 서버의 부담이 가중될 수 있습니다.
- SSR(Server Side Rendering) 방식의 애플리케이션에 적합한 방식입니다.
세션 기반의 자격 증명 방식은 인증된 사용자의 상태를 유지하기 위한 전통적인 방식입니다.
세션의 경우 서버 확장 시, 세션 불일치 문제가 발생할 수 있지만 Sticky Session, Session Clustering, Session 저장소의 외부 분리 등의 작업을 통해 보완하고 있습니다.
===========================================================================
토큰 기반 자격 증명 방식
세션 기반 인증이 인증 정보를 서버에 저장하는 방식이라면,
토큰 기반 인증은 인증 정보를 클라이언트가 직접 들고 있는 방식입니다.
이때 인증 정보가 토큰의 형태로 브라우저의 로컬 스토리지(혹은 쿠키)에 저장됩니다.
JWT의 경우 디지털 서명이 존재해 토큰의 내용이 위변조 되었는지 서버측에서 확인할 수 있습니다.
토큰 기반 인증에서는 사용자가 가지고 있는 토큰을 HTTP 의 Authorization 헤더에 실어 보냅니다.
이 헤더를 수신한 서버는 토큰이 위변조 되었거나, 만료 시각이 지나지 않은지 확인한 이후
토큰에 담겨있는 사용자 인증 정보를 확인해 사용자를 인가합니다.
✅ 토큰 기반 자격 증명의 특징
- 토큰에 포함된 인증된 사용자 정보는 서버 측에서 별도의 관리를 하지 않습니다.
- 생성된 토큰을 헤더에 포함해 request 전송 시, 인증된 사용자인지를 증명하는 수단으로 사용됩니다.
- 토큰 내에 인증된 사용자 정보 등을 포함하고 있으므로 세션에 비해 상대적으로 많은 네트워크 트래픽을 사용합니다.
- 기본적으로 서버 측에서 토큰을 관리하지 않으므로 보안성 측면에서 조금 더 불리합니다.
- 인증된 사용자 request의 상태를 유지할 필요가 없기 때문에 서버의 확장성 면에서 유리하고, 세션 불일치 같은 문제가 발생하지 않습니다.
- 토큰에 포함되는 사용자 정보는 토큰의 특성상 암호화가 되지 않기 때문에 공격자에게 토큰이 탈취될 경우, 사용자 정보를 그대로 제공하는 셈이 됩니다. 따라서 민감한 정보는 토큰에 포함하지 말아야 합니다.
- 기본적으로 토큰이 만료되기 전까지는 토큰을 무효화시킬 수 없습니다.
- CSR(Client Side Rendering) 방식의 애플리케이션에 적합한 방식입니다.
토큰의 경우, 기본적으로 토큰 무효화를 할 수 없지만 key/value 쌍의 형태로 저장되는 Redis 같은 인메모리 DB에 무효화시키고자 하는 토큰의 만료 시간을 짧게 주어 해당 토큰을 사용하지 못하게 하는 등의 방법을 사용해 토큰 무효화 문제를 보완하고 있습니다.