HTTP 프로토콜은 무상태(Stateless) 특성을 가지고 있습니다. 즉, 서버는 클라이언트의 이전 요청을 기억하지 못합니다.
"로그인한 사용자가 다음 페이지로 이동하면 다시 로그인해야 한다면?"
이런 불편함을 해결하기 위해 쿠키와 세션을 사용하여 HTTP에 상태 정보를 유지(Stateful)합니다.
클라이언트(웹 브라우저)에 저장되는 작은 데이터 파일입니다.
| 요소 | 설명 |
|---|---|
| Name | 쿠키를 구별하는 키 (중복 불가) |
| Value | 쿠키에 저장된 값 |
| Domain | 쿠키가 유효한 도메인 |
| Path | 쿠키가 사용되는 경로 |
| Expires | 쿠키의 만료 기한 |
(Chrome기준) 개발자도구 → Application → Storage → Cookies에서 확인 가능합니다.
@RestController
@RequestMapping("/api")
public class AuthController {
public static final String AUTHORIZATION_HEADER = "Authorization";
@GetMapping("/create-cookie")
public String createCookie(HttpServletResponse res) {
addCookie("Tom Auth", res);
return "createCookie";
}
// 쿠키 생성 메서드 (범용적으로 사용 가능하도록 static으로 선언)
public static void addCookie(String cookieValue, HttpServletResponse res) {
try {
// Cookie Value에는 공백이 불가능하므로 인코딩 처리
cookieValue = URLEncoder.encode(cookieValue, "utf-8")
.replaceAll("\\+", "%20");
// Name-Value로 Cookie 객체 생성
Cookie cookie = new Cookie(AUTHORIZATION_HEADER, cookieValue);
// 쿠키가 유효한 경로 설정 (모든 경로에서 사용 가능)
cookie.setPath("/");
// 만료 시간 설정 (30분)
cookie.setMaxAge(30 * 60);
// Response 객체에 Cookie 추가하여 브라우저로 전송
res.addCookie(cookie);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e.getMessage());
}
}
}
@GetMapping("/get-cookie")
public String getCookie(@CookieValue(AUTHORIZATION_HEADER) String value) {
System.out.println("value = " + value);
return "getCookie : " + value;
}
핵심 포인트
@CookieValue 애노테이션을 사용하여 쿠키의 Name으로 Value를 간편하게 추출할 수 있습니다.서버에서 클라이언트의 상태를 일정 시간 동안 유지하기 위해 사용합니다.
JSESSIONID=12A345)@GetMapping("/create-session")
public String createSession(HttpServletRequest req) {
// 세션이 존재하면 기존 세션 반환, 없으면 새로운 세션 생성 후 반환
HttpSession session = req.getSession(true);
// 세션에 정보 저장 (Name-Value 형식)
session.setAttribute(AUTHORIZATION_HEADER, "Tom Auth");
return "createSession";
}
핵심 포인트
req.getSession(true): 세션이 없으면 생성, 있으면 반환JSESSIONID라는 이름으로 자동 저장됩니다.@GetMapping("/get-session")
public String getSession(HttpServletRequest req) {
// 세션이 존재하면 반환, 없으면 null 반환 (새로 생성하지 않음)
HttpSession session = req.getSession(false);
// 세션에 저장된 값을 Name으로 조회
String value = (String) session.getAttribute(AUTHORIZATION_HEADER);
System.out.println("value = " + value);
return "getSession : " + value;
}
핵심 포인트
req.getSession(false): 세션이 없으면 null 반환 (생성하지 않음)getAttribute()로 세션에 저장된 값을 가져올 때는 형변환(Casting)이 필요합니다.| 구분 | 쿠키(Cookie) | 세션(Session) |
|---|---|---|
| 저장 위치 | 클라이언트 (브라우저) | 서버 |
| 사용 예시 | "오늘 하루 보지 않기" | 로그인 정보 저장 |
| 만료 시점 | 설정한 만료 시간까지 (브라우저 종료 후에도 유지 가능) | 브라우저 종료 시 / 로그아웃 시 / 서버 설정 시간 동안 재요청 없을 시 |
| 용량 제한 | 도메인당 약 180개, 쿠키당 4KB | 서버 메모리가 허용하는 한 제한 없음 |
| 보안 | 취약 (클라이언트에서 조작 가능) | 비교적 안전 (서버에 저장) |
| 속도 | 빠름 (서버 요청 불필요) | 상대적으로 느림 (서버 조회 필요) |
참고: 실제 프로젝트에서는 쿠키와 세션을 함께 사용하여 각각의 장점을 살립니다. 예를 들어, 세션 ID는 쿠키에 저장하고 실제 사용자 정보는 서버의 세션에 저장하는 방식입니다.