웹 브라우저는 1990년에 처음 등장하였고, 쿠키는 4년 뒤인 1994년에 등장했다. 알다시피 쿠키는 클라이언트 사이드에서 데이터를 저장할 수 있는 최초의 기술이다. 이는 다시 말해, 4년이라는 꽤 긴 시간 동안 클라이언트 사이드에 데이터를 저장할 방법이 없었다는 것이다. 인증 구현에 대한 이해도가 어느 정도 있는 사람이라면, 다음과 같은 의문이 들 수 있을 것이다.
그럼 대체 어떻게 세션을 유지했던걸까?
HTTP는 기본적으로 하나의 요청에 대한 응답을 완료하면, 연결 상태를 끊어 버린다. 또한, 기본적으로 이전에 받았던 요청 정보를 굳이 기억하고 있지 않는다. 이 말은 곧, 클라이언트 측에서 인증이 필요한 요청을 할 때마다 인증 정보를 함께 전달해야 한다는 것이다. 그렇지 않으면 지금 요청하고 있는 클라이언트가 누군지, 서버 측에서 정확히 알 방법이 없기 때문이다.
요청에 대한 응답을 완료한 후 연결을 끊는 HTTP 통신의 특징을 "비연결성" 이라고 하며, 이전 요청에 대한 정보를 저장하지 않는 특징을 "무상태성"이라고 한다.
현실에 빗대어 표현하자면, 단골로 가는 편의점에서 담배를 살 때마다 신분증을 검사하는 셈이라고 보면 된다. 아이러니한 것은 이 클라이언트에 대한 인증 정보를 session id 라는 형태로 서버에서 발급해준다는 것인데, 지가 신원을 보증해 놓고 뒤돌아서면 까먹어버리는 것이다. 이를테면 이런 시나리오다.
System: 클라이언트가 서버로 입장하였습니다.
To 클라이언트 From 서버 : "니 이름은 이제부터 덕배여"
A few moments later...
System: 클라이언트가 서버로 "다시" 입장하였습니다.
To 서버 From 클라이언트 : "저 덕밴데, 덕배에 대한 정보 주세요"
To 클라이언트 From 서버 : "누구시죠?"
참으로 어이없는 시나리오다. 귀찮긴 하지만, 덕배는 본인이 덕배라는 것을 증명하기 위한 신분증을 제시하면 되는데, 당시에는 클라이언트 측에서 신분증을 들고 있을만한 마땅한 수단이 없었다. 왜냐하면, 쿠키 이전에는 "클라이언트 사이드에 데이터를 저장할 수 있는 방법이 없었기" 때문이다. 서버에서 session id를 발급해줘도, 이를 들고 있을 수단이 없었다.
굳이 저장소라는 개념까지 가지 않아도,
JS 전역 변수에 저장하면 되는거 아니야?
아쉽게도 쿠키는 1994년에, 자바스크립트는 1995년에 등장했다. 그래서 api 요청 url에 사용자 인증 정보 (일반적으로 session id) 를 박아넣는 미친 짓을 하거나, 숨겨진 폼 필드를 통해 세션을 유지하는 등의 방식을 사용했다. 서버에서 HTML 문서를 응답해줄 때, 아래 코드처럼 session id를 아예 element에 박아서 보내줬던 것이다.
// GET 요청
<a href="/api/resource?sessionId=abc123">Go to Resource</a>
// POST 요청
<form action="/submit" method="POST">
<input type="hidden" name="sessionId" value="abc123">
<button type="submit">Submit</button>
</form>
GET 요청의 경우는 "URL 리라이터" 방식, POST 요청의 경우는 "숨겨진 폼 필드" 방식
User agent의 아이피 정보를 통해 식별하는 방법 역시, ip를 동적으로 할당받거나 공유 네트워크를 사용하는 환경에서는 쓸모가 없었다. 이 때, 이 상황을 답답하게 지켜보고 있던, 넷스케이프의 한 개발자가 이런 생각을 했다.
클라이언트 측에도 저장소 있으면 되잖아
그렇게 등장한 것이 지금의 쿠키이다. 쿠키가 동작하는 과정을 7단계로 정리하면 아래와 같은데, 쿠키를 통해 클라이언트는 서버에게 "요청하고 있는 내가 누구인지"를 알려 줄 수 있는, 이른바 신분증을 제시할 수 있게된 것이다.
1. 클라이언트는 적절한 인증 정보를 입력하여 서버로 전송
2. 서버는 인증 정보를 확인한 후, 고유의 session id를 발급
3. Cookie에 session id를 저장한 뒤 응답 헤더에 포함
4. 응답 헤더로 전달받은 Cookie는 클라이언트 측에 저장
5. 이후 서버로 요청할 때 자동으로 쿠키가 요청 헤더에 포함되어 전송
6. 서버는 요청 헤더에 담긴 session id를 확인
7. 세션 저장소를 통해 인가된 사용자인지 확인 후, 적절한 응답을 전송
참고로 쿠키라는 이름은, 포춘 쿠키라는 단어에서 따온 것이라고 한다. 포춘 쿠키 안에 작은 메시지가 들어있듯, HTTP 통신 과정에서 작은 데이터 쪼가리가 함께 움직이는 것이 닮았다고 생각했기 때문이다. 여기서 "작은 데이터 쪼가리"라고 칭하는 이유는, 쿠키가 4kb라는 제한된 용량을 갖고 있기 때문이다. 왜냐하면 쿠키는 별다른 옵션이 설정되어 있지 않을 경우, 모든 http 요청마다 함께 전송되기 때문에, 원치않은 오버헤드를 방지하기 위하여 용량 제한을 작게 설정한 것이다.
'브라우저 기본 개념' 카테고리의 다른 글
.js 인지 .jsx 인지가 정말 중요할까? (2) | 2024.11.13 |
---|