웹 환경에서 사용자와 시스템 간에 데이터를 교환하기 위해 HTTP 방식을 사용한다. HTTP 통신은 요청과 응답에 의해 동작하며 가장 중요한 특징은 Stateless다. 문자 그대로 번역하면 State(상태) + less(없음) 을 의미한다.
각각의 HTTP 통신(요청/응답)은 독립적 이기 때문에 과거의 통신(요청/응답)에 대한 내용을 전혀 알지 못한다. 그러므로 매 통신마다 필요한 모든 정보를 담아서 요청을 보내야 한다. 비유를 하자면, 마치 이미 자기소개를 한 사람에게 계속해서 똑같은 내용으로 자기소개를 해야하는 것과 같다.
만약 로그인 후 상품 구매나 개인정보 수정 같이 여러번의 통신(요청/응답)의 진행 과정에서 연속된 데이터 처리가 필요한 경우에 Stateless의 특징에 따라 매번 로그인을 위한 인증정보를 같이 보내주어야 한다.
위와 같은 불편함을 없애고자 일부 정보에 대해서 Stateful 상태를 유지할 필요가 있다. 이를 위해 Session과 Cookie 또는 Token 같은 기술을 사용할 수 있다.
동일한 클라이언트(사용자)가 브라우저를 통해 웹 서버에 접속한다고 가정해보자. 이 때 접속 시점으로부터 브라우저를 종료해 연결을 끝내는 시점까지 들어오는 일련의 Request를 하나의 상태로 본다. 또한 그 상태를 일정하게 유지하여 클라이언트와 웹 서버가 논리적으로 연결된 상태를 session
이 수행한다.
서버는 Session에 대한 정보를 저장한다. 클라이언트에게는 Sesssion을 구분할 수 있는 ID를 부여한다. 이것을 Session ID라고 한다. 클라이언트가 Request를 보낼 때 해당 Session ID를 함께 보냄으로써, 클라이언트의 상태를 확인 할 수 있다.
Cookie는 클라이언트의 컴퓨터에 저장되는 데이터 파일이다. Cookie에는 이름, 값, 만료 날짜/시간(저장기간), 경로 정보 등으로 구성되어 있다. Cookie는 하나의 도메인 당 20개를 가질 수 있으며, 1개 당 4Kbyte를 넘길 수 없다는 특징이 있다.
서버에서는 HTTP Response Header에 Set-Cookie 속성을 이용, 클라이언트에게 Cookie를 제공하여 저장한다. 클라언트는 HTTP Request에 저장된 Cookie를 함께 전달한다. 서버는 이전의 통신에서 사용된 클라이언트의 정보들을 파악할 수 있게 된다.
예를 들어 장바구니 기능의 경우 과거에는 로그인을 해야지만 사용할 수 있었지만 최근엔 Cookie를 이용하여 로그인을 하지 않은 상태로 장바구니에 상품을 담을 수 있게 됐다. 또한 Cookie를 통해 사용자별로 다른 정보를 표시하는 것이 가능하고, 사용자의 행동과 패턴을 분석할 수 있기 때문에 최근 더욱 중요한 개념으로 부상했다.
[그림1] Session based Authentication flow
Token의 사전적 의미는 버스 요금, 자동판매기 등에 사용하기 위한 동전 모양의 주조물 이다. 웹에서의 토큰도 이와 비슷한 의미를 가지고 있다. 우리는 Token으로 버스를 탈 권리 또는 자동판매기에서 상품을 구매할 권리를 가지게 된다. 이처럼 웹에서의 Token 또한 해당 서비스를 이용할 수 있는 권리를 부여한다.
조금 더 설명하자면 Token은 제한된 리소스에 대해 일정 기간 동안 접근할 수 있는 권한을 캡슐화한 것이다. Token은 일반적으로 의미를 알 수 없는 임의의 문자열 형태로 사용자에게 발급된다. 또한 제한된 리소스의 접근 권한을 캡슐화 할 뿐만 아니라 접근 할 수 있는 리소스의 범위와 접근 가능한 기간도 통제할 수 있다.
[그림2] Token based Authentication flow
상태 정보를 서버측에서 관리(session) 하지 않고 사용자 측에서 관리하기 때문에 서버의 상태를 Stateless하게 유지한다. 따라서 서버측에서는 사용자로부터 받은 Request만을 가지고 작업을 수행 할 수 있다.
서버의 상태를 Stateless 하게 유지 한다는 것은 사용자와 서버 사이에 관계가 없다는 의미도 된다. 일반적으로 Session 기반 인증에서는 로그인 상태를 유지하기 위해 최초 로그인 시 Request 한 서버로 계속 Session ID를 보내주어야 한다. 하지만 Token 기반의 인증 방식은 이러한 관계가 존재하지 않기 때문에 서비스를 운영 중인 어떤 서버로든 Request를 보낼 수 있다. 덕분에 Token 기반의 인증 방식을 사용하면 서버의 확장에 유리하다.
클라이언트가 서버로 요청을 보낼 때 더 이상 Cookie를 전달하지 않으므로 CSRF 공격을 방지하는 데 도움된다. 하지만 토큰 환경의 취약점이 존재할 수 있으므로 이에 대비해야 한다.
Token 기반의 인증 시스템에서는 토큰을 통해 권한의 범위를 지정 할 수 있다. 이를 이용하여 KaKao, Facebook, Google 등과 같은 소셜 계정을 이용하여 다른 웹서비스에서도 로그인을 할 수 있다.
서버 기반 인증 시스템의 문제점 중 하나인 CORS를 해결할 수 있습니다. 애플리케이션과 서비스의 규모가 커지면 여러 기기들을 호환시키고 더 많은 종류의 서비스를 제공하게 된다. 토큰을 사용한다면 어떤 기기, 어떤 도메인에서도 토큰의 유효성 검사를 진행한 후에 요청을 처리할 수 있다.