최근 새로운 프로젝트를 시작하며 인증(Auth)과 관련된 API 연동을 하는데 인증 관련 API 연동을 한 경험이 다수 있음에도 불구하고 여전히 헷갈리는 개념들을 이번에~ 한큐에~ 정리해보고자 한다.
인증을 공부하다 보면 "쿠키 vs 토큰" 이라는 표현을 자주 보게 된다.
하지만 이 둘은 서로 대체 관계가 아니라, 역할이 완전히 다르다❗️
쿠키(Cookie)는 저장 방식이고, 토큰은 저장되는 데이터의 한 종류다.
그래서 쿠키 자체를 토큰과 비교하는 것부터가 개념적으로 맞지 않는다. 맙소사

쿠키는 서버가 브라우저에 저장하도록 지시할 수 있는 작은 데이터다.
쿠키의 목적은 간단하다.
서버가 사용자를 기억하기 위함🧘
웹사이트에 처음 방문하면, 브라우저는 서버에 요청(Request)을 보낸다.
서버는 이에 대한 응답(Response)을 보내는데, 이 응답에는 다음과 같은 것들이 포함될 수 있다.

즉, 서버는 매 요청마다 "아, 이 사용자는 예전에 이런 정보를 가지고 있었구나"라고 판단할 수 있게 된다!
쿠키는 도메인 단위로 제한된다.
예를 들어, youtube.com이 발급한 쿠키는 youtube.com으로 요청할 때만 전송된다.
다른 사이트에서는 해당 쿠키에 접근하거나 전송할 수 없다.
쿠키는 서버가 정한 유효기간(Expires/Max-Age)에 따라 유지된다.
쿠키는 인증 정보만 저장하는 용도가 아니다!
예를 들어 웹사이트 언어 설정, 다크 모드 여부, 사용자 UI 설정 등에도 사용이 되는데 그 중 웹사이트 언어 설정의 경우, 사용자가 웹사이트에서 언어를 변경하면 서버는 해당 언어 정보를 쿠키에 저장해 둘 수 있다.
이후 사용자가 다시 방문하면, 브라우저는 쿠키를 요청과 함께 보내고 서버는 쿠키에 저장된 언어 설정을 기반으로 해당 언어의 페이지를 제공한다👏
그런데 쿠키를 이해하다 보면 자연스럽게 이런 의문이 생긴다.(실제로 내가 궁금했던 점들이다..)
이 질문에 답하기 위해서는 HTTP의 특성부터 다시 짚고 가야 한다.
HTTP는 stateless(무상태) 프로토콜이다.
즉, 서버는 이전 요청을 기억하지 않고 모든 요청은 완전히 독립적으로 처리된다
서버 입장에서는 "이 요청을 보낸 사용자가 방금 로그인한 사람인지" 알 방법이 없다❗️
그래서 등장한 개념이 바로 사용자를 어떻게 기억할 것인가이고, 그 해답이 세션(Session)과 토큰(token)이다.
쿠키 자체가 인증 방식은 아니다.
이 포인트를 잘 기억해야 한다. 쿠키는 단지 서버가 브라우저에 데이터를 저장하게 하고, 이후 요청마다 그 데이터를 자동으로 전달해주는 수단이다.
이 쿠키를 이용해
이렇게 방식이 나뉜다.
세션 방식은 서버가 사용자의 상태를 직접 기억하는 방식이다.
Session ID 생성Session DB에 Session ID <-> 사용자 정보 저장Session ID를 쿠키에 담아 브라우저로 전달즉, 중요한 정보는 전부 서버에 있고, 브라우저는
Session ID만 들고 다닌다
🙋♀️ 그래서 계정 정지, 강제 로그아웃, 특정 사용자 차단 같은 기능이 중요한 서비스에 적합하다! 그냥 Session을 삭제해버리면 되기 때문이다...
그래서 실제 서비스에서는 세션 정보를 Redis 같은 *인메모리DB로 분리하여 관리하기도 한다.
* 인메모리 DB란 데이터를 디스크가 아닌 주기억장치(RAM)에 저장하는 데이터베이스임
세션 방식은 쿠키에 의존한다.
하지만 모바일 앱(IOS/Android) 같은 네이티브 환경에서는 쿠키 사용이 제한적이다.
이때 자연스럽게 등장하는 방식이 토큰(Token) 기반 인증이다.
토큰은 서버가 발급한 임의의 String이다.
세션과 달리, 서버가 사용자 상태를 직접 저장하지 않고 토큰 자체를 인증 수단으로 사용한다.
이 방식에서는 서버가 "이 사용자가 누구인지"를 기억하지 않는다.
JWT는 토큰의 한 종류로, 차이점은 토큰 안에 사용자 정보가 들어있다는 점이다.
JWT에는 보통 사용자 ID, 만료 시간, 권한 정보와 같은 정보가 들어 있고, 서명을 통해 위변조 여부를 검증한다.
그래서 서버 확장이 쉽고, 대규모 트래픽 환경에 유리하다는 장점이 있다.
그렇다면 JWT가 좋기만 한가?? 그건 아니다. 다음과 같은 한계를 가진다.
그래서 실무에서는 짧은 만료시간의 AccessToken, 긴 만료시간의 RefreshToken을 함께 사용하는 구조가 많다.
내가 했던 모든 프로젝트에서도 대부분 이런 구조였음
쿠키 -> "어떻게 전달할까"
세션/토큰 -> "무엇을 기억할까"
정도로 아주 간단하게 정리할 수 있을 것 같다.
쿠키를 단순히 "브라우저 저장소"로만 이해하면 세션과 토큰 구조가 계속 헷갈린다 💦
공부하다보니 HttpOnly, Secure, SameSite 등등.. 더 공부해야 할 게 늘어났지만 정리하고 나니 현재 내가 진행하고 있는 서버의 흐름을 이해하기가 훨씬 명확해진 것 같다..
다음 글은 더 공부하고 또 정리해야것다
.
.
.
.
.
Thanks to 노마드코더, chatGPT
잼써염