[JSP·Servlet] 세션(Session)과 쿠키(Cookie) — 상태 유지의 두 가지 방법
목차
로그인 인증과 객체 바인딩
객체 바인딩을 하는 이유는, 회원 가입에 성공하면 다른 객체들도 그 사실을 알아야 하기 때문이다.
MemberDAO dao = new MemberDAO();
String user_name = dao.memberLogin(vo); // 로그인 처리 구현
// user_name에 값이 있으면 인증 성공, 없으면 인증 실패
if (user_name != null && !"".equals(user_name)) {
// 인증 성공 → 세션에 사용자 정보 저장
HttpSession session = request.getSession();
session.setAttribute("userId", user_id);
session.setAttribute("userName", user_name);
} else {
// 인증 실패 → 세션 초기화 후 오류 메시지 설정
request.getSession().setAttribute("userId", "");
request.getSession().setAttribute("userName", "");
request.getSession().setAttribute("msg", "사용자 정보가 올바르지 않습니다.");
}
return "redirect:" + ctx + "/memberList.do";
HttpSession은 request.getSession()으로 얻는다. 로그인에 성공하면 userId·userName이 세션에 setAttribute되어 객체 바인딩된다.
회원 인증을 확인하려면 세션 객체를 가져와 userId의 값을 꺼내면 된다.
하나의 PC에서 브라우저 두 개를 띄우면, 서버 입장에서는 두 명이 접속한 것으로 처리된다.

로그인에 성공하면 세션 기록을 읽어 서비스하고, 실패하면 다시 로그인 페이지로 리다이렉트한다.
세션(Session)이란?
Request(요청) 와 Response(응답) 가 생성될 때마다 새로운 객체가 만들어진다. 다른 페이지로 포워딩(forwarding)할 때 request.setAttribute로 바인딩한 데이터를 넘길 수 있지만, 이는 포워딩 범위 내에서만 유효하다. 리다이렉트처럼 새 요청이 발생하면 기존 request 객체는 소멸된다.

JSP는 세션에서 꺼낼 수 있다. A 페이지에서 인증하고 성공하면 서비스하고, 아니면 리턴(로그인 페이지로 돌아감)한다.
쿠키(Cookie)란?
쿠키 = 흔적 (과자를 먹으면 흔적이 남는다)
클라이언트가 서버에 요청하면, 서버는 클라이언트를 식별하기 위해 수강권(쿠키) 을 만들어 클라이언트에게 내려보낸다.

| 구성 요소 | 설명 |
|---|---|
| 클라이언트 측 쿠키 | 서버가 발급한 세션 식별자(수강 번호) 보관 |
| 서버 측 캐비넷(세션 저장소) | 수강 번호에 해당하는 데이터 보관 |
캐비넷은 수강 번호(세션 ID)가 있어야만 사용 가능하다. 클라이언트와 서버가 이렇게 연결되어 있는 것이 바로 세션이다.
- 첫 방문: 수강 번호가 없으므로 서버가 새로 발급해 쿠키로 내려보낸다.
- 재방문: 브라우저가 쿠키(수강 번호)를 request 객체에 담아 서버로 전달한다.

번호만 같으면 자신의 캐비넷을 마음대로 사용할 수 있다. 이 메모리 공간에 setAttribute해두면 어디서든 꺼내 쓸 수 있다.

getSession()의 동작 원리
클라이언트가 처음 방문했는지 여부를 서버가 판단해야 할 필요가 있다.


- 세션이 있는 경우: 기존 세션 메모리에서 값을 꺼내 사용한다.
- 세션이 없는 경우: 새 세션을 생성하고 쿠키로 클라이언트에 내려보낸다.
로그인 성공 시 세션을 생성하기 전에, 이미 세션이 존재하는지 먼저 확인해야 한다.
request.getSession()을 호출하면:
- 이미 세션이 있으면 → 기존 세션 객체를 반환한다.
- 없으면 → 새 세션을 생성하고, 세션 ID를 쿠키로 클라이언트에 내려보낸다.

getSession()이 세션 생성 + 쿠키 발급까지 한 번에 처리한다.

로그인 성공 후 세션을 만들고, 성공 사실을 세션에 저장한다.
세션을 이용한 페이지 인증
A.jsp, B.jsp, C.jsp 같은 여러 페이지에서 session.getAttribute로 userId를 꺼내 null이 아니면 인증된 사용자로 판단한다.
단, 동일한 브라우저(클라이언트)인 경우에만 같은 세션을 공유할 수 있다.

| 브라우저 | 세션 | 메모리 공간 |
|---|---|---|
| 브라우저 A | session-100 | session-100 전용 메모리 |
| 브라우저 B | session-200 | session-200 전용 메모리 |
모든 페이지가 세션 인증 여부를 비교·확인하는 것이 상태 인증 방법이다.

로그아웃: 세션 제거
클라이언트가 서버에 요청할 때 요청 정보가 담기는 곳이 Request이다.
package kr.bit.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MemberLogoutController implements Controller {
@Override
public String requestHandler(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 세션을 가져와서 세션을 제거
// 세션을 제거하는 방법
// 1. 강제로
String ctx = request.getContextPath(); // MVC06
request.getSession().invalidate();
// 2. 브라우저를 종료하는 것(JSESSIONID 브라우저 쿠키에 저장)
// 3. 세션이 종료될 때까지 기다리는 것(세션 타임아웃: 30분 = 1800초)
return "redirect:" + ctx + "/memberList.do";
}
}
세션 제거 방법은 세 가지다.
| 방법 | 설명 |
|---|---|
invalidate() 강제 제거 | 즉시 세션 삭제 |
| 브라우저 종료 | JSESSIONID 쿠키가 소멸되어 세션 연결 끊김 |
| 세션 타임아웃 대기 | 톰캣 기본값 30분(1800초), web.xml에서 설정 가능 |