로그인하면 왜 계속 로그인 상태로 있을까 — 쿠키, 세션, 토큰
웹사이트에 한 번 로그인하면, 그 뒤로는 페이지를 이리저리 옮겨 다녀도 로그인 상태가 그대로 유지됩니다. 장바구니에 담은 물건도 남아 있고, 내 이름도 화면 위에 계속 떠 있습니다. 너무 당연해서 의문을 품은 적이 없을지도 모릅니다. 그런데 사실 이것은 저절로 되는 일이 아닙니다.
“왜 자꾸 로그아웃돼요”, “자동 로그인은 어떻게 되는 거예요”, “쿠키를 차단하면 왜 로그인이 안 되나요” 같은 질문의 답이 모두 한 묶음으로 이어져 있습니다. 이 글에서는 로그인 상태가 유지되는 원리를 쿠키, 세션, 토큰이라는 세 단어로 풀어 보겠습니다. 코드는 나오지 않습니다.
웹은 원래 방금 본 사람도 기억하지 못합니다 #
먼저 의외의 사실부터 짚겠습니다. 웹은 기본적으로 사용자를 기억하지 못하도록 만들어졌습니다.
웹브라우저와 서버는 HTTP라는 약속으로 대화합니다. 그런데 이 대화에는 특이한 성질이 있습니다. 요청 하나하나를 서로 별개로 취급한다는 점입니다. 방금 어떤 화면을 보여 준 서버라도, 바로 다음 요청이 들어오면 그 사람을 처음 보는 손님처럼 대합니다. 직전에 무슨 일이 있었는지 기본적으로 기억하지 않습니다.
이 성질 덕분에 웹은 단순하고 튼튼하게 동작하지만, 그대로 두면 곤란한 점이 생깁니다. 로그인 화면에서 아이디와 비밀번호를 정확히 넣어도, 다음 화면으로 넘어가는 순간 서버는 그 사람이 누구였는지 잊어버립니다. 페이지를 옮길 때마다 다시 로그인해야 한다면 아무도 그런 서비스를 쓰지 않을 것입니다. 그래서 “이 사람은 방금 로그인한 그 사람"이라는 사실을 어딘가에 들고 다니게 하는 방법이 필요합니다.
쿠키는 브라우저가 보관하는 작은 쪽지입니다 #
이 문제를 푸는 첫 번째 도구가 쿠키입니다. 쿠키는 서버가 브라우저에게 건네주는 작은 쪽지라고 생각하면 됩니다.
로그인에 성공하면 서버는 “이 사람은 확인됐음"이라는 표시가 담긴 쪽지를 브라우저에 건넵니다. 브라우저는 이 쪽지를 받아 보관해 두었다가, 같은 사이트에 요청을 보낼 때마다 자동으로 함께 내밉니다. 서버는 들어온 요청에 붙은 쪽지를 보고 아까 그 사람임을 알아봅니다. 페이지를 옮겨도 로그인이 유지되는 것은 이 쪽지가 매 요청마다 따라다니기 때문입니다.
놀이공원 입구에서 손목에 채워 주는 밴드와 비슷합니다. 한 번 입장을 확인받고 밴드를 차면, 안에서 놀이기구를 탈 때마다 표를 다시 끊지 않아도 손목만 보이면 됩니다. 쿠키를 차단하면 로그인이 안 되는 이유도 여기 있습니다. 밴드 받기를 거부한 셈이라, 서버가 매번 누구인지 알아볼 길이 없어집니다.
세션은 정보를 서버가 쥐고 번호표만 건넵니다 #
쿠키에 무엇을 담느냐에 따라 방식이 갈립니다. 그중 하나가 세션입니다.
세션 방식에서는 중요한 정보를 서버가 직접 보관합니다. 누가 로그인했고 어떤 권한을 가졌는지를 서버 쪽 보관함에 넣어 두고, 사용자에게 건네는 쿠키에는 그 보관함을 가리키는 번호표만 담습니다. 옷가게에 외투를 맡기고 번호표만 받아 드는 것과 같습니다. 외투에 해당하는 실제 정보는 가게가 보관하고, 손님은 번호표만 들고 다니다가 나갈 때 내밉니다. 이 번호표를 세션 ID라고 부릅니다.
이 방식의 장점은 통제하기 쉽다는 것입니다. 서버가 정보를 쥐고 있으므로, 문제가 생기면 해당 번호표를 무효로 만들어 곧바로 로그아웃시킬 수 있습니다. 대신 사용자가 많아지면 서버가 보관해야 할 정보도 함께 늘어납니다.
토큰은 정보를 사용자가 들고 다니게 합니다 #
또 다른 방식은 토큰입니다. 세션과 반대로, 정보를 서버가 쥐고 있는 대신 사용자에게 통째로 들려 보냅니다.
로그인에 성공하면 서버는 “이 사람은 누구이고 무엇을 할 수 있다"는 내용이 담긴 표를 발급합니다. 이 표가 토큰입니다. 사용자는 이후 요청마다 이 표를 함께 내밀고, 서버는 표가 위조되지 않은 진짜인지만 확인하면 됩니다. 손님이 정보를 직접 들고 다니므로, 서버는 따로 보관함을 두지 않아도 됩니다.
여기서 당연한 걱정이 생깁니다. 사용자가 들고 다니는 표라면 내용을 마음대로 고칠 수 있지 않을까요. 그래서 토큰에는 위조를 가려내는 봉인이 들어갑니다. 내용을 조금이라도 바꾸면 봉인이 깨져 서버가 곧바로 가짜임을 알아챕니다. 흔히 쓰이는 토큰 형식을 JWT라고 부르는데, 이름까지 외울 필요는 없습니다. 정보를 검증 가능한 형태로 사용자가 들고 다닌다는 발상만 기억하면 충분합니다.
토큰 방식은 서버가 일일이 기억하지 않아도 되어 규모를 키우기 좋습니다. 대신 한 번 내준 표는 만료되기 전까지 거두기가 까다로워서, 강제 로그아웃 같은 통제는 세션보다 손이 더 갑니다. 세션과 토큰 중 무엇을 쓸지는 이런 장단점을 견주어 정합니다.
그래서 이런 일들이 설명됩니다 #
이 원리를 알면 평소 겪던 여러 일이 한 번에 풀립니다.
- 자동 로그인 체크박스. 체크하면 쿠키나 토큰의 유효 기간을 길게 잡아, 브라우저를 닫았다 열어도 한동안 로그인이 유지됩니다. 체크하지 않으면 보통 더 짧게 유지되다 풀립니다.
- 갑자기 로그아웃되는 일. 유효 기간이 지나 쪽지나 표가 만료됐거나, 보안을 위해 서버가 해당 정보를 무효로 만든 경우입니다.
- 공용 컴퓨터 경고. 쿠키가 그대로 남아 있으면 다음 사람이 그 쪽지를 그대로 쓸 수 있습니다. 그래서 공용 컴퓨터에서는 로그아웃이 중요합니다.
- 보안과 HTTPS. 쿠키나 토큰은 사실상 출입증입니다. 오가는 길에서 누군가 가로채면 그 사람이 나인 척할 수 있습니다. 통신을 암호화하는 HTTPS가 중요한 이유가 여기 있습니다.
왜 비개발자가 알면 일이 편해지는가 #
- 로그인 문의에 정확히 답할 수 있습니다. 로그아웃이 자꾸 풀린다는 문의를 받았을 때, 유효 기간이나 쿠키 설정처럼 짚어 볼 곳을 함께 떠올릴 수 있습니다.
- 버그를 잘 신고할 수 있습니다. 어떤 브라우저에서, 자동 로그인을 켰는지, 언제부터 풀리는지를 함께 전하면 원인을 찾기가 훨씬 빨라집니다.
- 개인정보 감각이 생깁니다. 쿠키와 토큰이 출입증이라는 점을 알면, 왜 함부로 공유하면 안 되는지, 왜 HTTPS와 로그아웃이 강조되는지 자연스럽게 이해됩니다.
마무리 #
한 번 로그인하면 상태가 유지되는 평범한 경험 뒤에는, 사용자를 기억하지 못하는 웹을 기억하게 만드는 장치가 숨어 있습니다. 브라우저가 자동으로 들고 다니는 쿠키, 정보를 서버가 보관하고 번호표만 건네는 세션, 정보를 검증 가능한 형태로 사용자가 들고 다니는 토큰까지 살펴봤습니다.
이 장치들이 결국 출입증이라는 점을 기억하면 로그인과 보안을 둘러싼 이야기가 한결 또렷해집니다. 브라우저와 서버가 요청과 응답을 주고받는 큰 그림이 궁금하다면 API가 무엇인지를, 이 정보를 노리는 공격이 어떻게 발전해 왔는지 궁금하다면 컴퓨터 바이러스와 랜섬웨어의 역사를 함께 읽어 보시길 권합니다.