클라이언트 인증 확인 방식(Cookie / Session /Token)
서버가 클라이언트 인증을 확인하는 방식으로는 쿠키, 세션, 토큰 방식 3가지가 있다. 면접을 앞두고 늘 대충 외우고 지나가기를 몇 번. 돌아서고 나면 제대로 기억나지 않는 이유는 클라이언트 인증(Authentication)과 인가(Authorization)에 대해 제대로 이해하고 있지 못하기 때문이라는 생각이 들어 제대로 정리해보기로 했다.
인증과 인가는 시스템의 자원을 유효한 사용자에게 공개하기 위해 존재한다.
인증(Authentication) 과 인가(Authorization)
인증(Authentication) | 인가(Authorization) |
사용자가 맞는지 검증하는 과정 (ex. 로그인) | 인증(로그인) 후 인증된 사용자에 대한 자원 접근 권한 확인 절차 (ex. CRUD가 모두 가능한 관리자와 CRU만 가능한 일반 회원) |
관리자 계정의 A가 위와 같은 인증과 인가 과정을 거쳐 로그인을 완료했다고 가정해보자. 이제 관리자 A는 관리자 게시판에서 여러 업무를 보게 될 것이다. 하지만, 여기서 작은 문제가 발생한다. 바로 서버가 방금 로그인한 클라이언트의 상태를 저장하지 않는다는 것이다. HTTP는 요청과 응답을 한 번 주고 받으면 바로 연결을 끊어버리는(Connectionless) 특성을 가진다. 따라서 방금 인증/인가를 받은 계정에 대해서도 한 번 통신이 오가고 끊어지면 서버 입장에서는 클라이언트가 이전에 인증을 거쳤는지 알 방법이 없어지는 것이다. 이를 HTTP의 비상태성 (Stateless)이라고 한다.
처음 HTTP가 등장하던 때는 단순히 HTML 문서를 주고받을 목적으로 설계 되었기 때문에 요청과 응답이라는 비교적 단순한 구조로도 작업이 가능했지만, 웹이 발전하고 확장되면서 위와 같은 문제들이 발생. 기존의 요청과 응답 내용이 담긴 상태가 유지되어야할 필요가 생겼다. 그렇게 등장한 것이 바로 Cookie ,Session, Token 방식이다.
Cookie 인증
쿠키는 웹서버가 사용자의 브라우저에 저장하는 텍스트파일로 Key-Value 형식의 문자열이다.
최초에 브라우저(클라이언트)가 서버에 요청을 보내면, 서버는 클라이언트 쪽에 저장하고 싶은 데이터를 응답헤더의 set-cookie에 담는다.
이 후 클라이언트가는 저장된 쿠키를 요청 헤어의 쿠키에 담아보내고, 서버는 이 정보를 바탕으로 요청한 클라이언트를 식별한다.
(ex. 유저 행동 추적 및 개인화 광고 표시등으로 활용)
Cookie 방식의 문제
- 보안에 취약. 요청시 쿠키 값이 있는 그대로 노출되기 때문에 유출 위험이 높다
- 브라우저간 공유가 불가능
- 쿠키는 4KB의 용량 제한이 있어 많은 정보를 담을 수 없음 (사이즈가 커질 수록 네트워크 부하 심해짐)
Session 인증
Session은 브라우저로 웹서버에 접속한 시점부터 브라우저를 종료해 연결을 끝내는 시점까지를 하나의 상태로 간주하여 그 상태를 일정하게 유지하는 기술이다. 잠깐 옆길로 새 로컬스토리지와 세션스토리지의 차이를 생각하면 편하다. 로컬스토리지에 담긴 데이터는 브라우저를 종료해도 사라지지 않지만, 세션 스토리지에 들어있는 데이터는 브라우저가 닫히면 세션도 끝나 사라진다.
세션은 쿠키와 비슷하게 SessionID-Value로 구성되어있다. 하지만, 앞선 쿠키의 문제점으로 인해 세선 인증에서는 사용자 인증정보가 서버내 세션 저장소에 저장되어 관리된다.
클라이언트가 로그인을 마치면 세션이 서버 메모리 상에 저장되며, 서버는 브라우저의 쿠키에 Session ID를 저장한다. 이후 브라우저는 사이트에 접속할 때마다 모든 요청에 Session ID를 쿠키에 담아 전송하고, 서버는 클라이언트가 보낸 Session ID와 서버에서 관리되고 있는 Session ID를 비교하여 인증을 진행한다.
Session 방식의 문제
- 클라이언트에 모든 정보를 저장하고 있는 쿠키보다는 아무 정보도 가지고 있지 않은 Session ID가 안전해보이지만, 여전히 ID가 탈취될 수 있는 위험에 노출되어있음
- 요청을 받으면 클라이언트 상태를 계속 유지해야 하기 때문에(stateful) 요청이 늘어나면 서버 부하가 심해짐
Token 인증
쿠키가 인증정보를 브라우저에, 세션이 서버에 저장하는 방식이라면 토큰 기반 인증은 인증 정보를 클라이언트가 들고 있는 방식이다. 토큰 기반 인증에서는 클라이언트가 서버에 접속하면, 서버에서 인증의 의미로 토큰을 부여한다. 클라이언트는 이 토큰을 들고 다시 서버에 요청을 할 일이있으면 요청 헤더에 발급받은 토큰을 심어 보낸다. 요청을 받은 서버는 해당 토큰을 서버에서 발급한 토큰과 대조하여 인증을 처리한다. Token 기반 인증은 서버를 기반으로 한 Session 인증 방식과 달리 상태를 유지할 필요가 없어 stateless한 것이 특징이다.