쿠키(Cookie), 세션(Session), 토큰(Token)의 등장배경
다음 3가지는 모두 웹 환경에서 상태 관리와 인증을 위해 등장한 기술이다. 우선 HTTP는 본질적으로 Stateless(상태가 없는) 프로토콜이다. 이는 서버가 각 요청을 독립적으로 취급하기 때문에 클라이언트 상태를 기억할 수 없다는 의미다. 따라서 상태 유지를 위해 클라이언트 측에 상태 정보를 저장할 수단이 필요했기 때문에 차례로 쿠키, 세션, 토큰이 등장했다.
쿠키 (Cookie)
브라우저(클라이언트)에 데이터를 저장하여 상태를 유지하는 방식
쿠키는 Key-Value 형식의 문자열 덩어리다. 클라이언트가 어떠한 웹 사이트를 방문할 경우, 그 사이트가 사용하고 있는 서버를 통해 클라이언트의 브라우저에 설치되는 작은 기록 정보 파일이다. 각 사용자마다의 브라우저에 정보를 저장하니 고유 정보 식별이 가능한 것이다.
쿠키의 동작방식
1️⃣ 브라우저(클라이언트)가 서버에 요청(접속)을 보낸다.
2️⃣ 서버는 클라이언트의 요청에 대한 응답을 작성할 때, 클라이언트 측에 저장하고 싶은 정보를 응답 헤더의 Set-Cookie에 담는다.
3️⃣ 이후 해당 클라이언트는 요청을 보낼 때마다, 매번 저장된 쿠키를 요청 헤더의 Cookie에 담아 보낸다. 즉, 클라이언트가 재방문 했을 경우, 웹 페이지 요청과 함께 쿠키 값도 같이 전송된다.
4️⃣ 따라서 지속적으로 로그인 정보를 가지고 있는 것처럼 사용할 수 있다.
쿠키 사용 예시
방문 사이트에서 아이디와 비밀번호를 저장하시겠습니까? 라고 나타나는 것은 쿠키로 저장하겠냐라는 뜻이다.
팝업이 나타날때 "오늘 이 창을 보지 않음"을 누르면 오늘 그 창이 뜨지 않는 것
쿠키의 단점
- 쿠키는 보안에 취약하다. 요청 시 쿠키의 값을 그대로 보내기 때문에 유출 및 조작 당할 위험이 존재한다.
- 쿠키에는 용량 제한이 있으므로 많은 정보를 담을 수 없다. 게다가 쿠키의 사이즈가 커질수록 네트워크 부하가 심해지기도 한다.
- 웹 브라우저마다 쿠키에 대한 지원 형태가 다르기 때문에 브라우저 간 공유가 불가능하다.
세션(Session)
웹 브라우저와 웹 서버 간의 연결 상태를 유지하기 위해 서버 측에 생성한 사용자 상태정보다.
세션의 동작방식
1️⃣ 클라이언트 (브라우저)가 서버에 최초로 요청을 보낸다.
2️⃣ 서버는 클라이언트를 식별하기 위해 세션 ID를 생성한다
3️⃣ 서버는 이 세션 ID를 쿠키(Set-Cookie
)에 담아 응답으로 클라이언트에게 보낸다. Set-Cookie: JSESSIONID=123456789; Path=/; HttpOnly
4️⃣ 클라이언트는 이후 요청 시마다 쿠키의 세션 ID(Cookie: JSESSIONID=123456789
)를 서버에 함께 전송한다.
5️⃣ 서버는 클라이언트가 보낸 세션 ID로 세션 저장소에서 세션 데이터를 조회하고 클라이언트를 식별해 처리한다.
세션의 단점
- 서버 메모리 사용이 증가한다.
- 서버에서 세션 저장소를 사용하므로 요청이 많아지면 서버에 부하가 심해진다.
토큰(Token)
서버가 인증된 사용자에게 발급한 암호화된 문자열로, 클라이언트는 이를 요청 시마다 제출하여 자신을 인증하며, 서버가 별도로 상태를 저장하지 않아도 사용자를 식별할 수 있도록 돕는다.
토큰의 등장배경
현대 웹 서비스는 확장성을 위해 분산 환경(여러 서버 운영)을 필수적으로 고려한다. 하지만 세션방식은 중앙화된 세션 저장소(세션 클러스터링, Redis)를 필요로 하고, 서버가 상태를 유지하는데 비용이 크게 든다. 따라서 서버가 상태를 관리하지 않고 클라이언트가 필요한 상태(사용자 정보, 인증 상태 등)를 암호화된 형태로 가지고 서버와 통신하는 방식이 고안되었다.
토큰 방식에는 OAuth와 JWT가 있지만. 목적이 다르다.
- 권한을 부여할 때는 OAuth 방식을 사용한다.
- 로그인 인증 할 때는 JWT 방식을 사용한다.
토큰을 사용하는 이유
- Token은 서버가 아닌 클라이언트에 저장되어 서버의 부담을 덜 수 있다.
- Cookie는 웹 브라우저에만 존재하여 모바일 앱 등의 다양한 클라이언트에서 인증을 처리할 수 없다.
- Token 방식은 Stateless를 기반으로 하여 확장성이 뛰어나다.
- 인증된 사용자임을 확인하기 위한 고유한 서명을 포함하여 위조된 요청인지 확인할 수 있다
토큰의 동작 방식
1️⃣ 사용자 로그인 및 토큰 발급
- 클라이언트 (브라우저)가 서버에 최초로 요청을 보낸다.
- 서버는 사용자 인증(ID, PW 등)을 진행한 후, 성공하면 토큰을 생성하여 클라이언트에 반환한다.
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." // 응답 예시
}
2️⃣ 클라이언트가 토큰 저장 및 요청
- 클라이언트는 받은 토큰을 저장하고 있다가 이후 요청 시 HTTP 요청 헤더에 첨부하여 서버로 전송한다.
// 요청 시 헤더 예시
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
일반적으로 헤더의 Authorization 필드를 사용하며, 앞에 Bearer
를 붙여 토큰을 보낸다.
3️⃣ 서버의 토큰 검증 및 처리
- 서버는 클라이언트가 보낸 토큰의 유효성(서명과 만료시간)을 확인한다.
- 유효한 토큰이라면, 서버는 토큰의 Payload(사용자 정보)를 통해 클라이언트를 식별한다.
- 인증에 성공하면 요청한 데이터를 반환하고, 실패하면 오류를 반환한다.
4️⃣ 토큰 만료 및 재발급
- 토큰은 일정 시간이 지나면 만료된다. 만료된 토큰은 서버에서 거부된다.
- 사용자는 다시 로그인하거나 Refresh Token을 이용해 새로운 토큰을 받을 수 있다.
토큰의 단점
- 쿠키/세션과 다르게 토큰 자체의 데이터 길이가 길어, 인증 요청이 많아질수록 네트워크 부하가 심해질수 있다.
- Payload 자체는 암호화되지 않기 때문에 유저의 중요한 정보는 담을 수 없다.
- 토큰을 탈취당하면 대처하기 어렵다. (따라서 사용 기간 제한을 설정하는 식으로 극복한다)
쿠키 vs 세션 vs 토큰(JWT) 비교 요약
구분 | 쿠키 | 세션 | JWT 토큰 |
---|---|---|---|
상태 관리 방식 | 클라이언트 저장 | 서버 저장 | 클라이언트 저장(토큰) |
등장 배경 | HTTP Stateless 문제 해결 | 쿠키의 보안 문제 해결 | 세션의 분산 환경 문제 해결 |
서버 부하 | 낮음 | 높음 | 낮음 |
보안 | 낮음 | 높음 | 중간(보완 필요) |
확장성 | 좋음 | 어려움 | 매우 좋음 |
데이터 관리 위치 | 클라이언트(브라우저) | 서버(메모리,DB) | 클라이언트 저장소 |
분산 환경 대응 | 복잡성 낮음 | 복잡성 높음 | 복잡성 낮음 |
3줄 요약
쿠키 : 웹 브라우저에 저장되는 정보
세션 : 서버가 나를 알아보는 방법
토큰 : 세션과는 또 다른 로그인 방식
'Backend > Spring' 카테고리의 다른 글
적절한 책임 분리 - Helper Class (0) | 2025.04.01 |
---|---|
BaseTimeEntity와 JPA Auditing: 왜 사용할까? (0) | 2025.04.01 |
JPA와 영속성 컨텍스트 (0) | 2025.03.31 |
[Spring 기초] 일정 관리 앱 만들기 (0) | 2025.03.26 |
JWT 토큰 인증 이란? (0) | 2025.03.25 |