쿠키(Cookie)와 세션(Session)의 차이점
1. 쿠키와 세션 개요
웹 애플리케이션에서 사용자의 로그인 상태 유지, 개인화된 정보 제공 등을 위해 **쿠키(Cookie)와 세션(Session)**이 사용된다. 두 개념은 비슷해 보이지만, 저장 위치, 보안성, 유지 방식에서 차이가 있다.
✅ 쿠키(Cookie)
- 클라이언트(사용자 브라우저)에 저장되는 데이터
- 사용자가 다시 방문할 때 해당 정보를 활용
- 로그인 유지, 장바구니 기능 등에 사용
✅ 세션(Session)
- 서버에 저장되는 데이터
- 사용자가 웹사이트를 떠나면 일정 시간이 지나 자동 삭제
- 보안이 중요한 정보 저장에 사용
2. 쿠키(Cookie)란?
2-1. 쿠키의 개념
쿠키는 웹 브라우저가 저장하는 작은 데이터 파일로, 사용자의 정보를 저장하여 재방문 시 동일한 환경을 제공할 수 있도록 한다.
예제: 로그인 유지, 자동 로그인, 장바구니 정보 저장 등
📌 쿠키의 주요 특징
- 클라이언트(브라우저)에 저장됨
- 데이터가 자동으로 서버에 전송됨 (HTTP 요청 시 포함됨)
- 작은 용량(4KB 이하) 제한이 있음
- 만료 기간 설정 가능 (예: 1시간, 1일, 1년 등)
2-2. 쿠키의 동작 방식
- 사용자가 웹사이트에 로그인하면, 서버가 쿠키를 생성하여 클라이언트(브라우저)에 저장
- 이후 사용자가 같은 웹사이트를 방문할 때, 브라우저는 저장된 쿠키를 서버로 전송
- 서버는 쿠키를 확인하여 사용자의 상태를 유지
📌 HTTP 응답에 쿠키 설정 예제
Set-Cookie: username=yeji; Expires=Wed, 01 Jan 2025 12:00:00 GMT; Path=/; Secure; HttpOnly
📌 브라우저가 서버에 요청 시 쿠키 포함 예제
GET /profile HTTP/1.1
Host: example.com
Cookie: username=yeji
2-3. 쿠키의 속성
속성 | 설명 |
Expires | 쿠키 만료 시간 (설정 안 하면 브라우저 종료 시 삭제) |
Max-Age | 쿠키의 유효 기간 (초 단위) |
Domain | 쿠키가 유효한 도메인 설정 |
Path | 쿠키가 적용될 URL 경로 |
Secure | HTTPS에서만 쿠키 전송 가능 |
HttpOnly | JavaScript에서 쿠키 접근 차단 (보안 강화) |
📌 보안이 중요한 쿠키 설정 예제
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict
✅ 쿠키의 장점
- 클라이언트에 저장되므로 서버 부담이 적음
- 일정 기간 동안 유지 가능하여 로그인 유지 기능 제공
🚨 쿠키의 단점
- 보안 취약(클라이언트 저장) → XSS(크로스 사이트 스크립팅) 공격 위험
- 데이터 크기 제한 (4KB) → 많은 데이터를 저장하기 어려움
3. 세션(Session)이란?
3-1. 세션의 개념
세션은 서버에서 관리하는 사용자 상태 정보이다. 사용자가 웹사이트를 방문하면 고유한 세션 ID가 생성되며, 이후 서버는 해당 세션을 통해 사용자의 상태를 유지한다.
📌 세션의 주요 특징
- 서버에 저장됨 → 쿠키보다 보안성이 높음
- 사용자가 웹사이트를 떠나거나 일정 시간이 지나면 자동 삭제
- 로그인 상태 유지, 결제 정보 관리 등 보안이 중요한 작업에 사용됨
3-2. 세션의 동작 방식
- 사용자가 로그인하면, 서버는 세션을 생성하고 세션 ID를 쿠키로 클라이언트에 전송
- 이후 사용자가 요청을 보낼 때, 브라우저는 세션 ID가 담긴 쿠키를 서버로 전달
- 서버는 해당 세션 ID를 확인하여 사용자 정보를 유지
📌 세션 생성 후 클라이언트에 쿠키 전달
Set-Cookie: sessionId=xyz123; HttpOnly; Secure
📌 클라이언트가 서버로 세션 ID 전송
GET /dashboard HTTP/1.1
Cookie: sessionId=xyz123
✅ 세션의 장점
- 보안성이 높음 (서버에서 관리되므로 클라이언트에서 변조 불가)
- 대량의 데이터 저장 가능
🚨 세션의 단점
- 서버에 부담이 큼 (사용자 수가 많아질수록 메모리 사용 증가)
- 서버에 저장되므로 확장성이 낮음
4. 쿠키와 세션 비교
비교 항목 |
쿠키(Cookie) | 세션(Session) |
저장 위치 | 클라이언트(브라우저) | 서버 |
데이터 용량 제한 | 4KB | 제한 없음 (서버 성능에 따라 다름) |
보안성 | 취약 (클라이언트 저장) | 보안 강함 (서버 저장) |
유지 기간 | 설정 가능 (수시간~수개월) | 브라우저 종료 또는 시간 초과 시 삭제 |
속도 | 빠름 | 서버에서 조회 필요 (속도 다소 느림) |
사용 예시 | 자동 로그인, 방문 기록 저장 | 로그인 상태 유지, 결제 정보 관리 |
✅ 쿠키가 적합한 경우
- 로그인 유지 (자동 로그인)
- 방문자 맞춤형 서비스 제공 (예: 다크모드 설정)
✅ 세션이 적합한 경우
- 로그인 인증
- 결제 처리 (보안이 중요한 작업)
5. JWT vs 세션 기반 인증
쿠키와 세션 외에도 **JWT(JSON Web Token)**를 활용한 인증 방식도 많이 사용된다. JWT는 세션을 저장하지 않고 토큰을 사용하여 인증을 수행하는 방식이다.
📌 JWT vs 세션 비교
비교 항목 |
JWT 인증 | 세션 기반 인증 |
저장 위치 | 클라이언트 (쿠키, 로컬스토리지) | 서버 |
확장성 | 우수 | 낮음 (서버 간 세션 공유 필요) |
보안성 | 토큰 탈취 시 위험 | 서버에서 관리 가능 |
사용 예시 | REST API, 마이크로서비스 | 일반적인 웹사이트 |
✅ JWT가 적합한 경우
- RESTful API 인증
- 마이크로서비스 아키텍처(MSA)
✅ 세션 기반 인증이 적합한 경우
- 일반적인 웹사이트 (세션 저장이 용이할 때)
6. 쿠키와 세션 사용 시 주의할 점
쿠키와 세션은 웹 애플리케이션에서 사용자 정보를 유지하는 데 필수적이지만, 잘못된 설정이나 보안 허점이 존재할 경우 개인정보 유출, 세션 하이재킹(Session Hijacking), 크로스사이트 스크립팅(XSS) 등의 보안 위험이 발생할 수 있다. 따라서, 안전하게 사용하기 위해 몇 가지 주의할 사항을 고려해야 한다.
6-1. 쿠키 사용 시 보안 고려 사항
쿠키는 클라이언트(사용자 브라우저)에 저장되기 때문에 다음과 같은 보안 조치를 취해야 한다.
1) Secure 속성 설정 쿠키가 HTTPS(보안 프로토콜)에서만 전송되도록 제한하여 HTTP를 통한 탈취를 방지할 수 있다.
Set-Cookie: sessionId=xyz123; Secure
2) HttpOnly 속성 설정 자바스크립트를 통한 쿠키 접근을 차단하여 XSS 공격을 방지할 수 있다.
session_regenerate_id(true); // 새 세션 ID 발급
📌 HttpOnly를 적용하면, 브라우저의 document.cookie를 통해 쿠키에 접근할 수 없으므로 XSS(크로스사이트 스크립팅) 공격을 방지할 수 있다.
3) SameSite 속성 설정 CSRF(Cross-Site Request Forgery, 사이트 간 요청 위조)를 방지하기 위해 쿠키가 다른 사이트에서 요청될 때 전송되지 않도록 제한할 수 있다.
if ($_SESSION['user_ip'] !== $_SERVER['REMOTE_ADDR']) {
session_destroy(); // 세션 강제 종료
}
- Strict → 쿠키가 오직 동일한 사이트에서만 전송됨
- Lax → 안전한 요청(GET)에서는 허용, POST 요청 등에서는 차단
- None → 모든 사이트에서 쿠키를 전송 (단, Secure 옵션 필요)
4) 민감한 정보 저장 금지 쿠키에 비밀번호, 신용카드 번호 같은 민감한 정보를 저장하지 않도록 해야 한다.
Set-Cookie: userId=12345; Secure; HttpOnly; SameSite=Strict
📌 암호화되지 않은 상태로 중요한 정보를 저장하면 쿠키 탈취(세션 하이재킹) 위험이 커진다.
6-2. 세션 사용 시 보안 고려 사항
세션은 서버에서 관리되지만, 세션 ID가 유출되면 해커가 세션을 가로채 사용자의 계정에 접근할 수 있다. 이를 방지하기 위해 다음과 같은 조치를 취해야 한다.
1) 세션 타임아웃 설정 세션이 너무 오래 유지되면 보안 위협이 커지므로, 일정 시간(예: 30분) 동안 활동이 없을 경우 세션을 만료시키는 것이 좋다.
ini_set('session.gc_maxlifetime', 1800); // 30분 후 자동 만료
2) 세션 ID 재발급 (Session Fixation 공격 방지) 로그인 후 새로운 세션 ID를 발급하여 기존 세션 ID가 계속 사용되지 않도록 해야 한다.
session_regenerate_id(true); // 새 세션 ID 발급
3) IP 및 User-Agent 검증 사용자의 IP 주소 또는 브라우저 정보(User-Agent)가 변경되었을 경우 세션을 무효화하여 보안성을 높일 수 있다.
if ($_SESSION['user_ip'] !== $_SERVER['REMOTE_ADDR']) {
session_destroy(); // 세션 강제 종료
}
4) HTTPS 사용 필수 세션 ID가 네트워크에서 탈취되지 않도록 HTTPS를 사용하여 전송해야 한다.
Set-Cookie: sessionId=xyz123; Secure; HttpOnly
📌 HTTPS가 적용되지 않은 사이트에서 세션을 사용할 경우, 네트워크 패킷을 감청하는 "세션 하이재킹(Session Hijacking)" 위험이 발생할 수 있다.
7. 쿠키와 세션의 실제 활용 사례
쿠키와 세션은 웹사이트에서 사용자 인증, 개인화 서비스, 트래킹(Tracking) 등 다양한 기능을 구현하는 데 활용된다.
7-1. 쿠키 사용 사례
1) 자동 로그인 기능 웹사이트에서 "로그인 상태 유지" 기능을 사용할 경우, 쿠키를 활용하여 사용자가 로그인할 때마다 정보를 입력하지 않아도 되도록 설정할 수 있다.
setcookie("rememberMe", "user123", time() + 3600 * 24 * 30, "/", "", true, true);
2) 장바구니 기능 사용자가 로그인하지 않아도 장바구니에 담은 상품을 유지할 수 있도록 쿠키를 이용한다.
3) 방문 기록 및 추천 시스템 사용자가 방문한 페이지를 쿠키에 저장하고, 이를 분석하여 맞춤형 콘텐츠를 추천하는 데 사용된다.
- 예제: 넷플릭스(Netflix) → 사용자의 시청 기록을 기반으로 추천 알고리즘 적용
7-2. 세션 사용 사례
1) 로그인 및 사용자 인증 로그인 정보를 서버의 세션에 저장하여 사용자가 브라우저를 닫거나 일정 시간이 지나면 자동 로그아웃되도록 한다.
$_SESSION['user'] = "yeji"; // 사용자 세션 저장
2) 결제 처리 및 보안이 중요한 데이터 관리 결제 정보나 개인 정보 같은 민감한 데이터는 세션을 활용하여 보관한다.
3) 다단계 폼 입력 (Wizard Form) 사용자가 여러 단계의 입력을 거치는 경우, 세션을 활용하여 입력값을 저장하고 페이지 이동이 가능하도록 한다.
- 예제: 온라인 쇼핑몰 → 사용자의 배송지 입력, 결제 정보 등을 저장
8. 쿠키와 세션 외에 고려할 수 있는 인증 방식
웹 애플리케이션의 보안 강화를 위해 JWT(JSON Web Token), OAuth, Redis 기반 세션 관리 등의 인증 방식도 활용할 수 있다.
8-1. JWT(JSON Web Token)
JWT는 토큰 기반 인증 방식으로, 세션과 달리 서버에서 상태를 저장하지 않는다.
- 장점: 확장성이 뛰어나며, REST API 인증에 적합
- 단점: 토큰이 탈취되면 보안 위협 발생 가능
📌 예제: API 기반 서비스 (마이크로서비스, 모바일 앱 로그인)
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "user123",
"exp": 1713139200
}
8-2. OAuth
OAuth는 사용자가 ID/PW를 입력하지 않고도 타사 계정을 통해 로그인할 수 있도록 지원하는 인증 방식이다.
- 예제: 구글, 네이버, 카카오톡 로그인
📌 실제 적용 사례
- 유튜브(Youtube): 구글 계정으로 로그인
- 페이스북(Facebook): 타사 앱 로그인 지원
8-3. Redis 기반 세션 관리
- 세션을 파일이 아닌 Redis 같은 인메모리 데이터베이스에 저장하여 성능을 향상시킬 수 있다.
- 대량의 사용자 접속을 처리하는 서비스(예: 대형 쇼핑몰, SNS)에 적합
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379');
session_start();