"세션 저장소의 키”로 쓰이는 쿠키 값
앞 글에서 세션은 이렇게 동작한다고 정리했다.
- 실제 데이터는 서버(톰캣)의 세션 저장소에 보관한다
- 브라우저는 쿠키로 “세션ID”만 들고 다닌다
- 서버는 그 세션ID로 세션 저장소에서 사용자 세션을 찾는다
여기서 그 “세션ID”가 바로 JSESSIONID의 값이다.
즉 JSESSIONID는 로그인 정보가 아니다.
서버가 로그인 정보를 찾기 위한 키(열쇠 번호) 이다.
JSESSIONID의 정체: 쿠키 이름이다 (값이 세션ID)
먼저 용어를 정확히 분리해야 한다.
- JSESSIONID : 쿠키의 이름(name) 이다
- JSESSIONID=abc123... : 여기서 abc123...이 세션ID(value) 이다
즉 브라우저는 쿠키로 이런 형태를 들고 다닌다.
- Cookie: JSESSIONID=abc123...
서버(톰캣)는 이 abc123... 값을 읽어서
세션 저장소에서 해당 세션을 찾는다.
세션 저장소 관점에서 보면 JSESSIONID는 “키”이다
서버 내부를 개념적으로 보면 보통 이런 구조이다.
- 세션 저장소(Map 같은 구조)
- key: 세션ID (쿠키 JSESSIONID의 value)
- value: 세션 한 칸(사용자별 attribute 저장 공간)
그래서 JSESSIONID 값이 바뀌면
서버 입장에서는 “다른 세션”으로 인식한다.
session.getId()가 곧 JSESSIONID 값이다
서블릿에서 세션ID를 직접 보면 더 직관적이다.
// ================================
// 세션ID 확인용 예시
// - session.getId() 값이 곧 JSESSIONID 쿠키의 value와 대응된다
// ================================
@WebServlet("/session/id")
public class SessionIdServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
HttpSession session = req.getSession(); // 없으면 생성 + JSESSIONID 발급 준비
String sessionId = session.getId();
resp.setContentType("text/plain; charset=UTF-8");
resp.getWriter().println("session.getId() = " + sessionId);
}
}
이 요청을 “쿠키 없는 상태”에서 처음 호출하면, 보통 이런 일이 벌어진다.
- 서버가 새 세션을 만들고 session.getId()를 생성한다
- 응답 헤더로 Set-Cookie: JSESSIONID=방금생성한ID가 내려간다
- 다음 요청부터 브라우저가 Cookie: JSESSIONID=그ID를 자동으로 붙인다
즉 session.getId() 값과 브라우저가 들고 다니는 JSESSIONID 값은 연결된다.
JSESSIONID는 “로그인 정보”가 아니라 “로그인 정보를 찾는 열쇠”이다
여기서 흔히 하는 오해가 있다.
- “JSESSIONID가 있으니까 로그인된 거 아닌가?”
아니다.
JSESSIONID가 있다는 건 단지
- “서버 세션 저장소에 접근할 수 있는 열쇠가 있다”
라는 뜻이다.
로그인 여부는 결국 세션 안에 저장된 값으로 결정된다.
// 로그인 여부 체크는 보통 이렇게 한다
HttpSession session = req.getSession(false);
String loginUser = (session == null) ? null : (String) session.getAttribute("loginUser");
if (loginUser == null) {
// 로그인 안 됨
}
즉 핵심은 이거다.
- JSESSIONID = 세션을 찾는 키
- loginUser = 로그인 상태를 판단하는 데이터(세션 attribute)
JSESSIONID는 언제 발급되는가
보통은 아래 시점에서 발급된다.
- req.getSession()을 호출했는데, 현재 요청에 유효한 세션이 없을 때
즉 “세션이 새로 만들어지는 순간”에 발급된다.
반대로 요청에 유효한 JSESSIONID가 이미 있고 세션이 살아 있으면
대부분은 새로 발급되지 않는다(그냥 기존 세션을 찾아서 쓴다).
JSESSIONID는 언제까지 유지되는가
여기서 두 개를 구분해야 한다.
1) 쿠키(JSESSIONID)의 유지
- 보통 톰캣이 발급하는 JSESSIONID는 “세션 쿠키” 형태가 많다
- 즉 브라우저를 종료하면 쿠키가 사라질 수 있다(설정에 따라 다를 수 있음)
2) 서버 세션의 유지(세션 타임아웃)
- 서버는 세션을 영원히 유지하지 않는다
- 일정 시간 동안 요청이 없으면 만료시키고 저장소에서 제거한다
즉 브라우저에 쿠키가 남아 있어도
서버에서 세션이 만료되면 그 JSESSIONID는 더 이상 유효하지 않다.
그 상태에서 다시 요청이 오면
- 서버는 “세션이 없네?”라고 판단하고
- 새 세션을 만들고
- 새 JSESSIONID를 다시 발급할 수 있다
세션을 강제로 종료하면 어떻게 되나: invalidate()
로그아웃은 보통 세션을 무효화하는 방식으로 처리한다.
// ================================
// 로그아웃 예시: 세션 무효화
// ================================
@WebServlet("/logout")
public class LogoutController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
HttpSession session = req.getSession(false);
if (session != null) {
session.invalidate(); // 서버 세션 저장소에서 해당 세션을 무효화
}
resp.sendRedirect(req.getContextPath() + "/login-form");
}
}
invalidate()의 의미는 단순하다.
- 서버 저장소에서 “그 세션 한 칸”을 폐기한다
그래서 브라우저가 기존 JSESSIONID 쿠키를 들고 다시 요청해도
서버는 세션을 못 찾아서 새 세션을 만들 수 있다.
(실무에서는 쿠키도 지우도록 응답을 추가하기도 하지만, 핵심은 서버 세션 무효화이다.)
핵심 정리
- JSESSIONID는 쿠키 이름이고, 그 값(value)이 세션ID이다
- 세션ID는 서버 세션 저장소에서 세션을 찾는 “키” 역할을 한다
- session.getId() 값이 세션ID이고, JSESSIONID 쿠키 값과 연결된다
- JSESSIONID가 있다고 로그인된 게 아니다(로그인 여부는 session attribute로 판단)
- 세션은 서버에서 timeout으로 만료되고, 로그아웃은 보통 invalidate로 처리한다
'Web > Web Basics' 카테고리의 다른 글
| [상태 유지와 공통 처리] 5. 리스너(Listener)란? (0) | 2026.03.30 |
|---|---|
| [상태 유지와 공통 처리] 4. 필터(Filter)란? (0) | 2026.03.30 |
| [상태 유지와 공통처리] 2-1. req.getSession()과 JSESSIONID, HttpSession (0) | 2026.03.30 |
| [상태 유지와 공통 처리] 2. 세션이란? (0) | 2026.03.30 |
| [상태 유지와 공통 처리] 1. 쿠키란? (0) | 2026.03.30 |