쿠키(Cookie), 세션(Session), 토큰(Token)
프로젝트를 위해 웹페이지에 사용자에 대한 인증/인가를 구현해야 했다.
이번 글에서는 HTTP의 특성과 함께 쿠키, 세션, 토큰의 개념을 이해하고 이를 웹 인증/인가에 활용하는 방법을 알아보려고 한다.
HTTP
HTTP(Hypertext Transfer Protocol)는 웹에서 데이터를 주고받기 위한 프로토콜로, 다음과 같은 특성을 가지고 있다.
- 클라이언트-서버: 클라이언트가 요청을 보내면 서버가 응답을 보내는 구조
- 무상태성(Stateless): HTTP는 각 요청이 독립적이며, 이전 요청의 상태를 저장하지 않음
- 비연결성(Connectionless): HTTP는 요청과 응답이 완료되면 연결이 끊어지며, 매 요청마다 새로운 연결을 맺음
이러한 특성 때문에 웹앱에서는 추가적인 방법을 사용하여 상태를 유지하고 사용자 인증을 관리해야 한다.
쿠키
쿠키는 웹 브라우저에 의해 클라이언트 측에 저장되는 작은 데이터 조각이다. 주로 사용자의 세션을 유지하거나 사용자 설정을 기억하는 데 사용된다. 서버는 HTTP 응답 헤더에 Set-Cookie 헤더를 포함하여 쿠키를 설정하고, 브라우저는 쿠키를 저장해 동일한 서버에 재 요청 시 저장된 데이터를 함께 전송한다.
Set-Cookie: sessionId=abc123; Path=/; HttpOnly; Secure
장점
- 간단한 상태 유지
- 클라이언트 측 저장으로 서버 자원 절약
단점
- 보안에 취약함
- 크기 제한 (최대 4KB)
쿠키는 단독으로 인증 방식으로 사용되지는 않으며, 주로 세션과 함께 사용된다. 서버는 사용자 인증 정보를 세션에 저장하고, 세션 ID를 쿠키에 저장하여 클라이언트와 서버 간의 인증 상태를 유지한다.
또한, 쿠키는 웹 브라우저에 의존하기 때문에 네이티브 애플리케이션에서는 사용할 수 없다. 네이티브 애플리케이션에서는 주로 토큰 기반의 인증 방식을 사용한다.
세션
세션은 서버 측에 사용자 정보를 저장하는 방법으로, 주로 사용자 로그인 상태를 유지하는 데 사용된다. 로그인, 로그아웃 시 별도 사용자로 인식하여 새로운 세션을 생성하며, 세션 ID를 통해 세션을 관리한다.
{
"sessionId": "abc123",
"userId": "user123",
"loginTime": "2024-05-23T12:00:00",
"expiryTime": "2024-05-23T13:00:00",
"userData": {
"username": "example_user",
"email": "user@example.com",
"role": "user"
}
}
장점
- 보안성이 높음 (서버에서 관리)
- 다양한 인증 및 인가 메커니즘을 지원
단점
- 서버 부담이 큼
- 확장성 문제 (서버 분산 시 관리가 어려움)
토큰
토큰은 사용자 인증 정보를 포함한 문자열로, 주로 API 인증에 사용된다. 토큰은 서버에서 생성되지만 클라이언트 측에 저장되어 서버에 전달된다. 대표적으로 JWT와 OAuth 토큰이 있다.
1) JWT (JSON Web Token)
JWT는 JSON 포맷을 사용한 토큰으로, Base64로 인코딩된 헤더, 페이로드, 서명으로 구성된다.
{
"header": {
"alg": "HS256",
"typ": "JWT"
},
"payload": {
"sub": "1234567890",
"name": "John Doe",
"admin": true
},
"signature": "HMACSHA256(
base64UrlEncode(header) + '.' +
base64UrlEncode(payload),
secret)"
}
2) OAuth 토큰
OAuth 프로토콜에서 사용되는 토큰으로, Access 토큰과 Refresh 토큰으로 구분된다.
Access 토큰은 일반적인 API 통신 시 사용되며, 유효기간이 짧다. Refresh 토큰은 Access 토큰의 갱신 시 사용된다.
GET /authorize?
response_type=code&
client_id=CLIENT_ID&
redirect_uri=REDIRECT_URI&
scope=read write&
state=STATE
장점
- 확장성
- 클라이언트 측 저장으로 서버 자원 절약
단점
- 토큰 탈취 시 악용 가능
페이지 요청 시, 서버는 해당 토큰이 유효한지만 검증하면 되므로 상태를 유지할 필요가 없다. (Stateless)
쿠키, 세션, 토큰 비교
쿠키 (Cookie) | 세션 (Session) | 토큰 (Token) | |
---|---|---|---|
저장 위치 | 클라이언트 (브라우저) | 서버 | 클라이언트 (브라우저) |
데이터 크기 | 제한 있음 (최대 4KB) | 제한 없음 | 제한 없음 (HTTP 헤더에 포함) |
보안성 | 낮음 (클라이언트 조작 가능) | 높음 (서버에서 관리) | 높음 (서명 및 암호화 가능) |
유효 기간 | 만료 시간 설정 가능 | 브라우저 종료 또는 서버 설정 시간 | 만료 시간 설정 가능 |
사용 용도 | 로그인 상태 유지, 사용자 설정 저장 | 사용자 인증 및 권한 부여 | 사용자 인증 및 권한 부여 |
전송 방법 | HTTP 요청 시 자동 전송 | 서버에서 직접 관리 | HTTP 요청 시 헤더에 포함 |
이번 글을 통해 HTTP의 특성과 함께 쿠키, 세션, 토큰의 개념을 이해하고 이를 웹 인증/인가에 어떻게 활용할 수 있는지 살펴보았다. 상황에 맞는 적합한 방식을 선택하여 안전하고 효율적인 인증 시스템을 구현하기 바란다.