◇ PART · BOARD

세션 깊이 보기

서버 쪽에 저장됨 + JSESSIONID

학습 목표

  • 세션이 어디에·어떻게 저장되는지 안다
  • JSESSIONID 쿠키가 어떻게 매개하는지 안다
  • HttpSession 의 메서드를 안다

⚠️ 「세션」 의 모호함

학생들의 혼란

"세션은 어디 있는 거예요? 쿠키랑 같이 쓰이는데 뭐가 다른지..."

🛠️ 세션 = 서버 쪽 보관함

JSESSIONID 가 「열쇠」

세션 정보는 서버 메모리 에 저장. 사용자에게는 「JSESSIONID」 라는 짧은 식별자만 쿠키로 발급. 다음 요청 시 그 ID 로 보관함을 찾아 정보 꺼냄.

흐름 — 세션 동작

① 첫 방문 (또는 로그인) 서버: 새 세션 보관함 생성 → ID 부여 (예: abc123) 서버: 보관함 안에 정보 저장 ┌──────────────────────────┐ │ JSESSIONID=abc123 │ │ ├─ loginUser: Member(...)│ │ └─ cart: [item1, item2] │ └──────────────────────────┘ 서버 → 브라우저: Set-Cookie: JSESSIONID=abc123 ② 다음 요청 브라우저 → 서버: Cookie: JSESSIONID=abc123 (자동 동봉) 서버: abc123 보관함에서 정보 꺼냄 → "환영합니다 OO님"

HttpSession — Spring 에서 사용


@PostMapping("/login")
public String login(String userId, String password,
                     HttpSession session) {       // ← 매개변수
    Member m = service.login(userId, password);
    if (m != null) {
        session.setAttribute("loginUser", m);     // 보관함에 저장
        return "redirect:/";
    }
    return "redirect:/login?error";
}

@GetMapping("/mypage")
public String mypage(HttpSession session, Model model) {
    Member u = (Member) session.getAttribute("loginUser");  // 꺼내기
    if (u == null) return "redirect:/login";
    model.addAttribute("user", u);
    return "mypage";
}

HttpSession 의 주요 메서드

메서드역할
setAttribute(name, value)보관함에 데이터 저장
getAttribute(name)데이터 꺼냄 (없으면 null)
removeAttribute(name)특정 데이터 삭제
invalidate()세션 폐기 (로그아웃)
getId()JSESSIONID 값
setMaxInactiveInterval(초)유효 시간 설정

세션 만료

기본 만료 시간: 30 분 (Tomcat 기본). 사용자가 30 분간 요청 안 보내면 세션 자동 삭제.


<!-- web.xml -->
<session-config>
    <session-timeout>60</session-timeout>  <!-- 60 분 -->
</session-config>

또는 코드에서:


session.setMaxInactiveInterval(60 * 60);  // 60 분 (초 단위)

JSESSIONID 도 사실 쿠키

F12 → Application → Cookies 에서 JSESSIONID 항목 확인.

  • Tomcat 이 자동으로 발급하는 쿠키
  • HttpOnly 자동 적용 (JS 접근 차단)
  • 이름은 JSESSIONID (자바 표준)
  • 값은 무작위 문자열 (예: F4E2A91B...)

👉 즉 「쿠키 vs 세션」 에서 세션도 쿠키를 쓴다. 차이는 「무엇이 보관함에 저장되느냐」.

JSP 에서 세션 접근


<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:if test="${not empty sessionScope.loginUser}">
    <span>${sessionScope.loginUser.name}님</span>
</c:if>

👉 EL 의 sessionScope 로 직접 접근. ${sessionScope.loginUser} = session.getAttribute("loginUser").

로그아웃 — invalidate()


@GetMapping("/logout")
public String logout(HttpSession session) {
    session.invalidate();
    return "redirect:/";
}
invalidate() 의 효과: - 서버 메모리의 보관함 삭제 - 보관함 안의 모든 attribute 삭제 - 다음 요청은 새 세션을 받게 됨 - 브라우저 쿠키의 JSESSIONID 도 의미 잃음

세션의 한계

대규모 환경에서
  • 서버가 여러 대 — A 서버에 만든 세션을 B 서버는 모름. Sticky Session 또는 세션 클러스터링(Redis) 필요
  • 메모리 부담 — 동시 사용자 10 만 명 = 10 만 보관함. 메모리 압박
  • 서버 재시작 시 사라짐 — 모든 사용자 강제 로그아웃

대안: 외부 캐시(Redis), JWT 토큰 등. 본 과정은 단일 서버 가정.

실험 — 세션 직접 보기

  1. 로그인
  2. F12 Application → Cookies → JSESSIONID 값 확인
  3. JSESSIONID 값을 임의로 변경 (인스펙터에서 편집)
  4. 새로고침 → 로그인 풀림 (세션 키 매칭 실패)
  5. 정상 JSESSIONID 로 복원 → 다시 로그인 상태

🔄 Before / After

전 차시 끝

세션은 서버에 있다는 정도만 안다.

이번 차시 끝

JSESSIONID 가 「열쇠」 임을 안다. HttpSession 메서드를 코드로 사용 가능.

정리

오늘 들고 가는 것

  • 세션 = 서버 메모리의 보관함
  • JSESSIONID = 보관함의 「열쇠」 (자동 발급 쿠키)
  • setAttribute / getAttribute / invalidate
  • JSP 의 sessionScope
  • 기본 만료 30 분