세션
Session
개념
로그인한 사람이 누구인지 서버가 요청과 요청 사이에 기억해 두는 상태로, 화면을 옮길 때마다 다시 묻지 않게 해 줍니다.
등장 배경
웹이 오가는 방식에는 기억이 없습니다. 요청 하나가 끝나면 서버는 방금 누가 무엇을 했는지 잊습니다. 이 성질은 서버가 수많은 사람을 감당하는 비결이기도 했지만, 화면이 여러 장으로 늘어나는 순간 문제가 됐습니다.
초기 사이트에서 이 불편은 이런 모양이었습니다. 아이디와 비밀번호를 넣어 들어가도 다음 장으로 넘어가면 처음 보는 사람이 됐습니다. 장바구니에 물건을 담고 다음 화면으로 가면 장바구니가 비어 있었습니다. 그래서 화면마다 로그인 상자를 붙여 두거나, 주소 끝에 아이디를 매달고 다니는 방법을 썼습니다. 주소에 매다는 쪽은 더 나빴습니다. 주소를 복사해 남에게 보내면 남이 내 계정으로 들어왔고, 브라우저 기록과 서버 로그에 그 값이 그대로 남았습니다.
인증, 즉 누구인지 확인하는 절차는 한 번이면 충분한데 그 결과를 이어 갈 자리가 없다는 것이 문제의 핵심이었습니다. 세션은 그 자리를 서버 쪽에 만든 장치입니다. 확인이 끝난 사람의 정보를 서버가 들고 있고, 브라우저에는 그 정보를 꺼낼 열쇠 하나만 쥐여 줍니다.
작동 방식
서버가 기억을 하나 만들어 두고 그 기억을 가리키는 열쇠만 브라우저에 내려 줍니다. 순서는 다섯 단계입니다.
- 로그인이 성공하면 서버가 이 사람의 정보를 담은 기록을 하나 만듭니다. 누구인지, 어떤 권한이 있는지, 언제 들어왔는지가 여기 들어갑니다.
- 그 기록에 아무도 못 맞힐 무작위 문자열을 이름표로 붙입니다. 이것이 세션 아이디입니다.
- 아이디만 응답에 실어 브라우저에 보냅니다. 브라우저가 알아서 보관했다가 다음 요청에 자동으로 붙여 주는 쿠키라는 작은 값에 담습니다.
- 이후 요청마다 브라우저가 그 쿠키를 함께 보내고, 서버는 아이디로 기록을 찾아 누구인지 알아냅니다.
- 정해진 시간이 지나거나 로그아웃을 누르면 서버가 기록을 버립니다. 그 순간 같은 아이디를 들고 와도 아무것도 나오지 않습니다.
기록 전체가 아니라 아이디만 내려보내는 것이 이 방식의 요점입니다. 브라우저에 있는 값은 사용자가 열어 보고 고칠 수 있습니다. 등급이 무료라는 정보를 브라우저에 두면 그 글자를 유료로 바꿔 보는 사람이 반드시 나옵니다. 아이디는 아무 뜻이 없는 문자열이라 고쳐 봐야 없는 기록을 가리킬 뿐입니다.
남는 질문은 그 기록을 어디에 두느냐입니다. 가장 쉬운 자리는 서버의 메모리이고, 서버가 한 대일 때는 잘 돕니다. 두 대가 되면 깨집니다. 요청을 여러 서버에 나눠 보내는 로드 밸런서 뒤에서는 같은 사람의 다음 요청이 다른 서버로 갈 수 있고, 그 서버에는 기록이 없어서 로그인한 적 없는 사람 취급을 받습니다. 배포도 같은 문제입니다. 서버를 새 코드로 갈아 끼우면 메모리가 비워지니 접속해 있던 사람이 전부 튕깁니다. 그래서 기록은 서버 밖 공용 저장소에 둡니다. 모든 서버가 같은 곳을 보므로 어느 서버로 요청이 가든 같은 답이 나옵니다. 저장소는 데이터베이스를 쓰기도 하지만, 읽고 쓰는 횟수가 많아 메모리에 두고 빠르게 꺼내 쓰는 종류를 주로 씁니다.
쓰이는 곳
로그인 유지가 가장 흔한 자리이고, 그 밖에도 요청과 요청 사이를 이어야 하는 곳이면 어디서나 쓰입니다.
- 로그인 상태. 한 번 확인한 사람을 계속 알아보게 합니다.
- 무엇을 할 수 있는지 확인하는 인가. 기록 안에 역할과 소속 팀이 들어 있어서, 관리자만 여는 화면을 요청할 때마다 데이터베이스를 다시 뒤지지 않아도 됩니다.
- 로그인 전의 임시 작업. 장바구니에 담아 둔 것이나 쓰다 만 양식이 여기 들어갑니다. 계정이 없는 사람에게도 세션은 만들어집니다.
- 여러 단계로 나뉜 흐름. 결제처럼 화면 서너 장을 거치는 과정에서 앞 화면의 선택을 뒤 화면이 알아야 할 때 씁니다.
기록이 서버에 있다는 성질에서 오는 쓰임도 있습니다. 서버가 기록을 지우면 그 사람은 그 자리에서 끊깁니다. 페이지덱에서 기업 고객의 담당자가 퇴사할 때 이 성질을 씁니다. 계정을 비활성으로 바꾸는 동시에 그 사람의 세션을 전부 지우면, 사무실에 열어 둔 탭에서도 다음 클릭부터 로그인 화면이 뜹니다. 서명된 값을 브라우저에 들려 보내는 JWT 방식은 이걸 바로 하지 못합니다. 서버가 기록을 갖고 있지 않아서 이미 발급한 값을 도로 거두지 못하고, 유효 기간이 끝날 때까지 그대로 통합니다.
실무 용례
"로그인이 자꾸 풀려요. 세션이 30분이라 그런가요?"
일정 시간 움직임이 없으면 서버가 기록을 버리는 설정이 짧게 잡혀 있느냐는 물음입니다.
"배포하고 나니까 다들 로그아웃됐어요. 세션이 서버 메모리에 있어서요."
기록을 서버 안에 두고 있어서 서버를 새로 띄울 때마다 접속자가 전부 튕긴다는 뜻입니다.
"탈퇴 처리할 때 세션도 같이 지워 주세요."
계정만 막고 기록을 남겨 두면 이미 열려 있던 화면에서는 한동안 계속 쓸 수 있다는 지적입니다.
페이지덱에서 이 문제가 실제로 났습니다. 태오가 점심시간에 배포를 올렸는데 그 순간 접속해 있던 사람들이 전부 로그아웃됐고, 쓰다 만 문서가 저장 안 된 채 날아갔다는 문의가 수아에게 몰렸습니다. 원인은 세션 기록이 서버 메모리에 있다는 것이었습니다. 서버가 한 대이던 시절에는 아무도 몰랐고, 배포가 잦아지면서 드러났습니다. 기록을 서버 밖 공용 저장소로 옮긴 뒤로는 배포와 로그인 상태가 서로 무관해졌습니다.
흔한 오해
세션과 쿠키를 같은 말로 아는 경우가 많습니다. 둘이 늘 붙어 다니고 개발자 도구에서도 나란히 보이니 그렇게 됩니다. 하지만 쿠키는 열쇠를 나르는 수단이고 세션은 서버에 있는 기록입니다. 열쇠를 쿠키가 아닌 다른 방법으로 나를 수도 있고, 쿠키에 세션과 무관한 값만 담을 수도 있습니다. 둘을 하나로 알면 문제가 났을 때 어디를 봐야 할지 모릅니다. 쿠키가 안 붙어 오는 것인지 기록이 이미 지워진 것인지에 따라 고칠 곳이 완전히 다릅니다.
브라우저를 닫으면 세션이 끝난다고 아는 것도 절반만 맞습니다. 브라우저를 닫을 때 사라지는 것은 쿠키에 담긴 열쇠뿐이고, 그것도 쿠키를 어떻게 설정했느냐에 달렸습니다. 서버의 기록은 제 만료 시각까지 그대로 남아 있습니다. 그래서 공용 컴퓨터에서 창만 닫고 자리를 뜨면 기록은 살아 있고, 로그아웃을 눌러야 서버가 그 기록을 버립니다.
자주 헷갈리는 용어
| 용어 | 서버가 무엇을 들고 있는가 | 세션과의 차이 |
|---|---|---|
| 무상태 | 아무것도 들고 있지 않음 | 요청에 필요한 정보를 매번 요청 자체에 실어 보내는 설계입니다. 서버를 늘리거나 껐다 켜기 쉬운 대신, 이미 내보낸 것을 도로 거두기 어렵습니다 |
같이 보면 좋은 페이지
마지막 업데이트 2026-09-16