- 세션의 정의, 배경
- 세션이 필요한 이유(HTTP 무상태성 보완)를 명확하게 알기
- 세션의 특징, 구조, 동작 과정
- 세션 기반 인증 워크플로우를 다이어그램과 예제로 알기
- 실무에서 안전하게 세션을 관리하는 방법(만료, 보안 옵션, 로그아웃)
세션(SESSION)
1. 정의
클라이언트(사용자)가 서버에 접속한 순간부터 접속을 끊을 때까지의 연결 상태
웹에서는 HTTP 프로토콜이 무상태성(Stateless)이므로, 서버가 사용자의 상태를 기억하지 못함
따라서 로그인 상태 유지, 장바구니 정보, 사용자 맞춤 화면 등을 제공하기 위해 세션이 필요함
즉 세션은 사용자의 상태 정보를 서버에 저장해두고, 이를 세션 ID(SESSION ID)라는 키로 식별하는 방식임
세션은 서버가 기억하는 "사용자의 임시 신분증"이다.
2. 특징
서버 중심 관리 : 사용자의 로그인 여부, 권한, 장바구니 정보 등을 서버가 직접 보관함
클라이언트는 세션 ID만 보관함 : 브라우저는 세션 자체가 아니라, 세션을 가리키는 고유 ID를 쿠키에 저장함
만료 가능 : 일정 시간 동안 요청이 없으면 세션을 종료(유휴 타임아웃)하거나, 최대 사용시간을 설정(절대 타임아웃)할 수 있음
보안 의존성 : 세션 ID가 유출되면 사용자의 정보가 탈취될 수 있음. 따라서 세션 ID를 안전하게 보호하는게 핵심임
세션
| 항목 | 설명 |
| 저장 위치 | 서버(메모리, DB, Redis 등등) |
| 클라이언트 역할 | 세션 ID를 쿠키에 저장하며 요청마다 전달함 |
| 만료 관리 | TTL(Time-To-Live), 유휴/절대 타임아웃 |
| 보안 이슈 | 세션 ID 탈취, 세션 고정(Session Fixation) 공격 |
세션 동작 방식
1. 세션 생성과 전달
- 사용자가 로그인시 서버는 아이디, 비밀번호 검증을 수행한다
- 검증에 성공하면 서버는 새로운 세션 객체(Session)를 생성하고, 사용자 ID와 관련 정보를 세션 저장소에 저장한다
- 서버는 해당 세션을 식별할 수 있는 세션ID를 생성한다
- 이 세션ID를 Set-Cookie 헤더에 담아서 브라우저에 전달함 (서버 -> 브라우저)
HTTP/1.1 200 OK
Set-Cookie: SESSION=abc123;
Path=/;
HttpOnly;
Secure;
Max-Age=1800 # 마지막은 세미콜론 안들어감
SESSION=abc123 : 서버가 발급한 세션 ID
HttpOnly : 자바스크립트 접근 방지(XSS 방어)
Secure : HTTPS에서만 전송함
Max-Age=1800 : 세션 유지 시간(초단위, 30분)
브라우저는 이 Set-Cookie값을 저장하고, 이후 동일한 도메인 요청마다 자동으로 전송함
2. 세션 확인 과정
- 사용자가 보호된 페이지에 접근하면 브라우저는 자동으로 요청에 Cookie 헤더를 포함한다 (브라우저 -> 서버)
- 서버는 요청 헤더의 세션 ID(abc123)를 확인함
- 서버는 세션 저장소에서 해당 세션 ID를 찾아, 사용자의 정보를 복원함
- 세션이 유효하면 요청을 정상 처리하고 응답한다
GET /mypage HTTP/1.1 # get요청
Host: example.com
Cookie: SESSION=abc123
3. 동작 워크플로우 다이어그램
4. Set-Cookie vs Cookie의 차이점 정리
| 헤더 | 방향 | 설명 | 예시 |
| Set-Cookie | 서버 -> 브라우저 | 서버가 쿠키를 생성/수정하도록 지시 | Set-Cookie; SESSION=abc123; Path=/; HttpOnly; Secure |
| Cookie | 브라우저 -> 서버 | 브라우저가 저장한 쿠키값을 전송함 | Cookie; SESSION=abc123 |
세션 관리 구현 예시
1. 디렉토리 구조 예시
- root/
- src/
- main/
- java/
- auth/
- Session.java : 세션 객체 정의
- SessionManager.java : 세션 생성/조회/만료 관리
- CookieUtil.java : 쿠키 파싱/생성 유틸
- AuthController.java : 로그인/로그아웃 엔드포인트
- auth/
- java/
- main/
- src/
2. 코드 예시(진짜 예시임)
Session.java
public class Session {
private String id; // 세션 ID
private String userId; // 사용자 ID
private long expiresAt; // 만료 시각
public Session(String id, String userId, long ttlSeconds) {
this.id = id;
this.userId = userId;
this.expiresAt = System.currentTimeMillis() + ttlSeconds * 1000;
}
public boolean isExpired() {
// expiresAt이 현재시간보다 작다면 만료됨
return System.currentTimeMillis() > expiresAt;
}
public String getId() {
return id;
}
public String getUserId() {
return userId;
}
}
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class SessionManager {
private Map<String, Session> store = new ConcurrentHashMap<>();
// 세션 생성 메서드
public Session create(String userId, long ttlSeconds) {
String id = UUID.randomUUID().toString();
Session session = new Session(id, userId, ttlSeconds);
store.put(id, session);
return session;
}
// 세션 조회
public Session find(String id) {
Session session = store.get(id);
// 검증로직
if (session == null || session.isExpired()) { // session이 없거나 만료됐다면
store.remove(id); // store에서 id를 제거함
return null;
}
return session;
}
// 세션 무효화 로직
public void invalidate(String id) {
store.remove(id);
}
}
세션 기반 인증의 보안 고려사항
세션 기반 인증은 편리하지만, 보안 위협에 취약할 수 있음
1. 세션 ID 보안
(1) 랜덤성 : 세션 ID는 충분히 긴 난수(UUID v4, 난수 발생기 등 사용)를 사용해야함
(2) 예측 불가능성 : 단순 중가하는 숫자나 시간 기반 ID는 공격자가 쉽게 예측할 수 있으므로 사용하지 말아야함
(3) 쿠키 보안 속성
- Secure : HTTPS 연결에서만 전송
- HttpOnly : JavaScript로 쿠키 접근 차단하기 : XSS 완화
- SameSite : 크로스 사이트 요청 제한하기 : CSRF 완화
(4) 고유성 보장 : 동일한 세션 ID가 동시에 재발급되지 않도록 보장함
Set-Cookie: SESSION=abc123xyz;
Path=/;
HttpOnly;
Secure;
SameSite=Lax;
Max-Age=1800
2. 세션 만료 정책
유휴 타임아웃(Idle Timeout) : 일정 시간 요청이 없으면 세션을 자동 만료시킴
절대 타임아웃(Absolute Timeout) : 세션이 생성된지 일정 시간이 지나면 무조건 만료시킴
강제 로그아웃 : 관리자가 특정 사용자의 세션을 강제로 만료시킬 수 있어야함
만료 정책 워크플로우
3. 세션 고정(Session Fixation) 방지
문제점 : 공격자가 미리 발급받은 세션 ID를 피해자에게 강제로 사용하게 하면, 로그인 후에도 공격자가 동일 세션을 이용할 수 있음
대책
- 로그인 성공시 새로운 세션 ID를 무조건 재발급함
- 권한 상승(일반 사용자 -> 관리자) 시에도 세션 ID를 다시 생성함
// 로그인 성공 시 항상 세션ID를 발급하는 로직 예시
Session newSession = sessionManager.create(userId, 1800);
response.addHeader("Set-Cookie", "SESSION=" + newSession.getId()
+ "; HttpOnly; Secure; SameSite=Lax");
4. 로그아웃 처리
서버 측 세션 무효화 : 세션 저장소에서 해당 세션 ID 삭제
클라이언트 쿠키 만료 지시 : Max-Age=0 또는 Expires 속성을 이용해서 브라우저 쿠키를 제거함
즉시 반영 : 로그아웃 요청 즉시 세션이 무효화되어야 하며, 남아있는 요청이 더이상 인증되지 않아야함
# 로그아웃시 쿠키 무효화 처리
Set-Cookie: SESSION=;
Path=/;
Max-Age=0;
HttpOnly;
Secure
5. 추가 고려사항
동시 세션 제어 : 동일한 사용자가 여러 기기에서 로그인할 경우, 정책적으로 허용할지 제한할지 결정하기
세션 하이재킹 대응 : 비정상적인 위치(IP, User-Agent 등등)에서 세션 접근 시 알림 또는 강제 만료처리하기
로그 및 모니터링 : 로그인/로그아웃, 세션 만료, 실패시도 등을 로깅하여 추적 가능성 확보하기
전송 계층 보안 : 세션 쿠키는 반드시 TLS(HTTPS)를 통해서 전송해야함
정리
| 항목 | 설명 |
| 세션 ID 보안 | 예측 불가능한 난수 + Secure/HttpOnly/SameSite 속성 |
| 만료 정책 | 유휴 타임아웃 + 절대 타임아웃 병행하기 |
| 세션 고정 방지 | 로그인 / 권한 상승시 새로운 세션 ID 발급 |
| 로그아웃 처리 | 서버 세션 무효화 + 쿠키 만료 지시 |
| 추가 고려사항 | 동시 세션 제어, 세션 하이재킹 탐지, 로깅 / 모니터링 |
'Spring Boot > 유저 관리 기능' 카테고리의 다른 글
| 기본 인증, 인코딩 : 기본 인증 (0) | 2026.03.09 |
|---|---|
| 쿠키와 세션 기반 인증 : 쿠키와 세션 보안 설정 (0) | 2026.03.08 |
| 쿠키와 세션 기반 인증 : 쿠키의 개념과 특성 (0) | 2026.03.05 |
| 유저 기능의 이해, 인증 개념 : 인증 워크플로우 (0) | 2026.03.04 |
| 유저 기능의 이해, 인증 개념 : 인증(Authentication) (0) | 2026.03.02 |