어떻게 다시 와도 날 기억해, 세션과 쿠키
앞에서 HTTP는 지난 요청을 기억하지 않아서 요청마다 우리를 처음 보는 손님처럼 대한다고 했다. 그런데 쇼핑몰에 한 번 로그인하면 한참 동안 로그인이 풀리지 않는다. 매번 잊어버리는 서버가 어떻게 나를 계속 알아보는 걸까? 비밀은 작은 통행증 한 장에 있어요.
잊어버리는 서버, 풀려야 할 로그인
웹 서버는 요청 하나를 처리하고 나면 우리를 깨끗이 잊는다. 그러니 다음 요청이 오면 또 처음 보는 손님처럼 대한다.
여기서 이상한 점이 하나 생긴다. 로그인은 한 번만 했는데 왜 페이지를 옮겨 다녀도 로그인이 풀리지 않을까? 서버가 정말로 매번 잊는다면, 페이지를 하나 열 때마다 아이디와 비밀번호를 다시 넣어야 맞아요.
방문 단추를 눌러 보자. 잊어버리는 서버는 매번 잊어서, 방문할 때마다 로그인이 풀리고 다시 로그인해야 해요.
보다시피 이래서는 너무 불편하다. 페이지를 열 때마다 로그인해야 한다면 금방 지쳐 버릴 거예요.
그렇다고 서버에게 손님 얼굴을 모두 외우라고 할 수도 없다. 요청에는 얼굴이 없고, 손님은 셀 수 없이 많다. 그래서 꾀를 하나 쓴다. 서버가 외우는 대신, 손님에게 작은 표를 한 장 쥐여 주는 것이다.
서버가 작은 통행증을 발급한다
손님이 처음 들어오면 서버는 응답에 작은 표를 한 장 실어 보낸다. 이 표를 쿠키라고 부르고, 브라우저가 받아서 보관한다. 표에는 번호가 하나 적혀 있다. '당신은 7번 손님' 같은 식이다.
놀이공원 입구에서 채워 주는 손목 띠를 떠올리면 쉬워요. 실제 번호는 남이 짐작하지 못하도록 길고 무작위한 글자로 만든다. 서버는 이 번호와 손님의 정보만 짝지어 두면 되니, 수많은 손님을 얼굴로 외울 필요가 없어요.
이제 손님의 손에 번호가 적힌 통행증이 생겼다. 서버는 이 번호를 그 손님과 이어서 자기 쪽 명단에 적어 둔다. 장바구니에 무엇이 담겼는지, 로그인했는지 같은 정보도 그 줄에 함께 적힌다.
중요한 점은 통행증을 손님이 들고 다닌다는 것이에요. 서버가 모든 것을 외우는 것이 아니라 손님이 자기 번호를 챙긴다. 그렇다면 이 통행증은 언제 다시 꺼내 보여 줘야 할까?
요청할 때마다 통행증을 보여 준다
브라우저는 받은 통행증을 넣어 두었다가, 같은 사이트에 요청을 보낼 때마다 알아서 함께 내민다. '저 7번 손님이에요' 하는 셈이다. 사람이 따로 할 일은 없어요.
요청 쪽지 한 귀퉁이에 번호를 적어 보내는 것과 같다. 그래서 서버는 요청만 보고도 누가 보냈는지 단번에 안다. 통행증에는 유효 기간도 적혀 있어서, 기간이 지나면 브라우저가 더는 내밀지 않는다.
방문 단추를 눌러 보자. 손님이 요청과 함께 통행증 번호를 매번 같이 내밀어요.
이제 손님은 요청할 때마다 같은 번호를 함께 보낸다. 서버 쪽에서 보면 요청이 올 때마다 번호가 딸려 오는 셈이다.
서버는 여전히 손님을 외우지 못하지만, 번호가 요청에 붙어 오니 문제가 없어요. 그렇다면 서버는 그 번호를 받아서 무엇을 할까? 자기가 적어 둔 명단과 맞춰 보면 된다.
아, 그 사람! 하고 알아본다
통행증 번호가 도착하면 서버는 적어 둔 명단을 펼친다. '7번이 누구였더라' 하고 찾아보는 것이다. 명단에서 7번을 찾으면 '아, 그 사람!' 하고 알아본다. 장바구니도 로그인 상태도 그 줄에 그대로 남아 있다.
이렇게 여러 번의 요청에 걸쳐 같은 손님이라는 것을 이어서 기억하는 것을 세션이라고 해요. 세션 덕분에 페이지를 옮겨 다녀도 로그인이 풀리지 않는다. 로그아웃을 누르면 서버가 명단에서 그 줄을 지우고, 통행증은 쓸모가 없어진다.
도착한 통행증 번호를 눌러 보자. 서버가 명단에서 그 번호를 찾아 '아, 그 사람!' 하고 알아보며 로그인을 이어 가요.
잊어버리는 서버였는데 이제는 우리를 척척 알아본다. 비결은 서버가 외운 것이 아니라, 손님이 통행증을 들고 다닌 데 있다. 서버는 번호와 명단만 맞춰 보면 되니 손님이 아무리 많아도 가볍게 다룬다.
그런데 조심할 점이 하나 있어요. 번호만 맞으면 누구든 그 손님으로 통과한다. 누군가 길 중간에서 남의 통행증 번호를 엿보거나 훔치면 어떻게 될까?
정리
한 줄로 모으면 이렇다. HTTP는 지난 요청을 기억하지 않아서 매번 처음 보는 손님처럼 대한다. 그래서 서버는 처음 온 손님에게 번호가 적힌 작은 통행증, 곧 쿠키를 건넨다.
브라우저는 요청할 때마다 그 통행증을 함께 보내고, 서버는 번호를 명단과 맞춰 '아, 그 사람!' 하고 알아봐요. 이렇게 같은 손님임을 이어서 기억하는 것이 세션이다. 기억하는 일은 손님의 통행증에 맡기고, 서버는 번호만 맞춰 보는 거예요.
핵심을 차례로 눌러 되짚어 보자. (건망증이 문제 → 통행증(쿠키) 발급 → 방문마다 보여 줌 → 아, 그 사람!(세션))
이제 서버가 어떻게 우리를 다시 알아보는지 알았다. 그런데 서버가 확인하는 것은 통행증 번호뿐이다. 그 번호를 든 사람이 정말 나인지까지는 알지 못한다.
그러니 번호가 길 위에서 남의 눈에 띄면 큰일이에요. 다음 레슨에서는 오가는 데이터를 자물쇠로 잠가 길 중간에서 엿보지 못하게 하는 HTTPS를 다룬다. 비밀번호로 정말 그 사람인지 확인하는 일은 보안 영역에서 자세히 살펴본다.