1. 세션(Session)
개념
- 세션은 사용자가 웹 애플리케이션에 접속한 상태를 서버 측에서 유지하는 기술입니다.
- 사용자가 로그인하거나 특정 작업을 수행하면 서버는 사용자를 식별하기 위해 세션 ID를 생성합니다.
- 세션 ID는 클라이언트(브라우저)에 쿠키로 저장되거나 URL 매개변수로 전달됩니다.
작동 원리
- 클라이언트가 서버에 요청을 보냄.
- 서버가 세션 ID를 생성하고 서버의 메모리(또는 데이터베이스)에 세션 데이터를 저장.
- 세션 ID는 쿠키를 통해 클라이언트로 전달됨.
- 이후 클라이언트는 요청 시마다 세션 ID를 서버로 전송하여 자신의 상태를 확인.
특징
- 상태 유지: 서버가 세션 데이터를 관리하므로 클라이언트의 상태를 기억할 수 있음.
- 보안: 서버 측에서 데이터가 관리되므로 클라이언트의 변조 위험이 적음.
- 유지 시간: 세션은 유효기간(예: 30분)이나 사용자의 로그아웃 등으로 만료됨.
2. 쿠키(Cookie)
개념
- 쿠키는 클라이언트(웹 브라우저)에 저장되는 작은 데이터 조각으로, 서버가 클라이언트를 식별하거나 설정 데이터를 유지하기 위해 사용됩니다.
- 주로 키-값 쌍으로 저장되며, 브라우저가 자동으로 서버로 쿠키를 전송합니다.
작동 원리
- 서버가 클라이언트에 응답할 때 쿠키를 설정(Set-Cookie 헤더 사용).
- 클라이언트는 브라우저에 쿠키를 저장.
- 이후 클라이언트가 같은 서버에 요청할 때 쿠키를 함께 전송.
특징
- 저장 위치: 클라이언트(브라우저)에 저장됨.
- 자동 전송: 쿠키는 요청 시마다 서버로 자동 전송되어 인증에 사용.
- 보안 이슈: 민감 정보를 평문으로 저장할 경우 중간자 공격(Man-in-the-Middle)이나 XSS 공격에 취약.
종류
- 세션 쿠키: 브라우저가 닫히면 삭제됨.
- 영구 쿠키: 만료 시간 설정 가능, 브라우저를 닫아도 유지됨.
3. 토큰(Token)
개념
- 토큰은 인증 및 권한 부여를 위한 작은 데이터 조각으로, 클라이언트와 서버 간에 안전하게 정보를 교환하는 데 사용됩니다.
- 토큰은 자가 포함(Self-contained) 방식으로 필요한 정보를 내부에 포함할 수 있음.
작동 원리
- 클라이언트가 인증 정보를 서버에 보냄(예: 사용자명과 비밀번호).
- 서버는 사용자를 검증하고, 검증된 사용자에게 토큰을 발급.
- 클라이언트는 토큰을 저장(예: 로컬 스토리지 또는 세션 스토리지).
- 클라이언트는 요청마다 토큰을 헤더(Authorization: Bearer 토큰)로 전송하여 인증.
특징
- Stateless: 토큰은 클라이언트에 저장되므로 서버는 사용자 상태를 유지하지 않음.
- 보안 강화: 토큰 자체에 서명이 포함되므로 위조 방지가 가능.
- 유효 기간: 토큰에 만료 시간이 포함되어 보안성을 향상.
4. JWT(Json Web Token)
개념
- JWT는 JSON 형식으로 데이터를 인코딩한 토큰입니다.
- 클라이언트와 서버 간 인증 및 정보 교환에 사용되며, URL-safe한 형식으로 인코딩되어 HTTP 요청의 헤더, URL, 또는 본문에서 안전하게 전송할 수 있습니다.
구조
JWT는 세 가지 부분으로 구성됩니다:
-
Header: 토큰 타입(JWT)과 서명에 사용된 알고리즘 정보를 포함.
{
"alg": "HS256",
"typ": "JWT"
}
-
Payload: 사용자 정보 또는 클레임(Claims)을 포함.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
-
Signature: 토큰 변조를 방지하는 서명.
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
특징
- 자가 포함(Self-contained): JWT는 필요한 정보를 자체적으로 포함.
- Stateless: 서버가 상태를 저장할 필요가 없음.
- URL-safe: Base64Url로 인코딩되어 URL에 안전하게 포함 가능.
보안 고려사항
- JWT 자체는 암호화되지 않으므로, 민감한 정보는 포함하지 말아야 함.
- 토큰 만료 시간(exp)을 설정하여 재사용 위험을 줄임.
5. 저장 위치
- 세션(Session):
- 데이터는 서버에 저장됩니다.
- 클라이언트 측에는 세션 ID만 전달되며, 이는 쿠키 또는 URL 매개변수로 클라이언트와 서버 간에 주고받습니다.
- 예: 서버의 메모리, 데이터베이스, 또는 파일 시스템에 저장.
- 쿠키(Cookie):
- 클라이언트의 브라우저에 저장됩니다.
- 데이터 자체(예: 세션 ID, 사용자 설정 등)가 클라이언트의 쿠키에 보관되며, 요청 시마다 서버로 전송됩니다.
- 토큰(Token):
- 데이터는 클라이언트 측에 저장됩니다(주로 로컬 스토리지 또는 세션 스토리지).
- 서버는 토큰을 저장하지 않고, 토큰 자체에 필요한 정보를 포함합니다(Stateless).
6. 인증과 상태 유지
- 세션(Session):
- 상태 기반 인증입니다.
- 서버가 사용자의 상태를 관리하고, 세션 ID를 통해 사용자와 상태를 매핑합니다.
- 서버 부하가 증가할 수 있으며, 확장성(Scalability)이 제한될 수 있음.
- 쿠키(Cookie):
- 상태 유지 도구입니다.
- 인증 자체보다는 세션 ID나 사용자 기본 설정과 같은 데이터를 저장하고 전송하는 데 주로 사용됩니다.
- 만료 시간을 설정하여 특정 기간 동안 유지 가능.
- 토큰(Token):
- 상태 비저장 인증입니다.
- 클라이언트가 토큰을 서버로 전달하며, 서버는 토큰의 유효성을 검증하여 인증합니다.
- 서버는 상태를 저장하지 않아 확장성이 좋음.
7. 보안
- 세션(Session):
- 상대적으로 안전합니다.
- 민감한 데이터는 서버에 저장되며, 세션 ID만 클라이언트에 전달되므로 데이터 변조 위험이 적습니다.
- 하지만, 세션 하이재킹(세션 ID 탈취) 공격에 취약할 수 있음.
- 쿠키(Cookie):
- 보안 설정이 중요합니다.
- Secure 속성: HTTPS에서만 쿠키를 전송.
- HttpOnly 속성: 자바스크립트를 통해 쿠키에 접근 불가능.
- 설정이 부실하면, XSS(크로스 사이트 스크립팅) 공격이나 중간자 공격에 노출될 위험이 있음.
- 토큰(Token):
- 서명(Signature)을 통해 변조 방지가 가능.
- 하지만, JWT처럼 서명이 있어도 데이터는 암호화되지 않으므로 민감한 정보를 포함하지 않아야 함.
- 유효 기간(exp)을 설정하여 오래된 토큰 사용 방지.
8. 유효 기간과 만료
- 세션(Session):
- 서버에서 세션의 유효 기간을 관리합니다.
- 기본적으로 세션은 브라우저를 닫으면 만료되지만, 만료 시간을 설정하여 브라우저가 열려 있어도 세션이 유지될 수 있음.
- 쿠키(Cookie):
- 쿠키의 만료 시간은 서버가 지정할 수 있습니다.
- 세션 쿠키는 브라우저가 닫히면 삭제되고, 영구 쿠키는 지정된 만료 시간까지 유지됩니다.
- 토큰(Token):
- 토큰 자체에 만료 정보(exp 필드)가 포함됩니다.
- 만료 시간이 지나면 토큰은 유효하지 않으며, 클라이언트는 새로운 토큰을 받아야 합니다.
9. 사용 사례
항목 | 세션(Session) | 쿠키(Cookie) | 토큰(Token) |
---|
사용 예 | 로그인 상태 유지, 장바구니 관리 | 사용자 환경 설정, 세션 ID 저장 | RESTful API 인증, OAuth 2.0 |
적합 환경 | 전통적인 웹 애플리케이션 | 간단한 상태 저장 | 모바일/SPA 환경, Stateless 서버 |
10. 성능과 확장성
- 세션(Session):
- 서버가 상태를 유지해야 하므로 서버 부하가 증가할 수 있습니다.
- 서버를 확장(예: 여러 대의 서버로 분산)하려면 세션 데이터를 공유하는 별도 저장소(예: Redis)가 필요합니다.
- 쿠키(Cookie):
- 서버 부하가 없지만, 클라이언트에 저장된 쿠키 데이터가 많아지면 브라우저와 서버 간 통신에 영향을 줄 수 있습니다.
- 토큰(Token):
- 서버는 상태를 유지하지 않아 확장성이 높습니다.
- 단, 토큰의 크기가 크면 네트워크 트래픽에 영향을 줄 수 있습니다.
JWT (Json Web Token) 상세 설명
JWT는 클라이언트와 서버 간 인증 및 데이터 교환을 위해 널리 사용되는 토큰 형식입니다. JWT는 안전하고 간단한 구조로 다양한 웹 애플리케이션에서 사용됩니다.
1. JWT의 구조
JWT는 Header, Payload, Signature 세 부분으로 구성되며, Header.Payload.Signature
형태의 문자열로 나타납니다.
- JWT의 메타데이터를 포함합니다.
- 두 가지 주요 정보:
- alg: 서명에 사용된 알고리즘 (예: HS256, RS256 등).
- typ: 토큰 타입 (JWT로 고정).
{
"alg": "HS256",
"typ": "JWT"
}
- Base64Url로 인코딩되어 JWT의 첫 번째 부분을 구성합니다.
1-2. Payload
- JWT의 데이터 부분으로, 사용자 정보나 클레임(Claims)을 포함합니다.
- 주요 정보:
- Registered Claims (사전 정의된 클레임):
iss
(Issuer): 토큰 발급자.
sub
(Subject): 토큰 주제(예: 사용자 ID).
aud
(Audience): 토큰 대상.
exp
(Expiration Time): 만료 시간.
iat
(Issued At): 발급 시간.
nbf
(Not Before): 특정 시간 이후에만 유효.
- Custom Claims (사용자 정의 클레임):
- 사용자 애플리케이션에서 필요한 정보(예: 사용자 이름, 권한 등).
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022
}
- Base64Url로 인코딩되어 JWT의 두 번째 부분을 구성합니다.
1-3. Signature
2. JWT의 작동 원리
- 클라이언트 인증 요청:
- 클라이언트가 사용자명과 비밀번호를 서버로 보냅니다.
- 서버 인증 후 JWT 생성:
- 서버는 사용자를 인증하고, 사용자 정보를 포함한 JWT를 생성하여 클라이언트로 반환합니다.
- 클라이언트 저장:
- 클라이언트는 JWT를 로컬 스토리지 또는 세션 스토리지에 저장합니다.
- 요청 시 JWT 전송:
- 클라이언트는 이후 요청마다 HTTP 헤더(예: Authorization: Bearer )에 JWT를 포함하여 서버로 전송합니다.
- 서버 검증:
- 서버는 JWT의 서명을 확인하고, Payload 정보를 기반으로 요청을 처리합니다.
3. JWT의 특징
3-1. 장점
- Stateless:
- 서버가 사용자 상태를 저장할 필요가 없습니다.
- 서버 부하를 줄이고 확장성이 뛰어납니다.
- 자가 포함(Self-contained):
- JWT에 필요한 정보를 모두 포함하므로 추가적인 데이터베이스 조회 없이 요청을 처리할 수 있습니다.
- URL-safe:
- Base64Url 인코딩 방식을 사용하여 URL, 헤더, 본문 등에 안전하게 포함될 수 있습니다.
- 빠른 검증:
- 서버는 서명을 확인하여 데이터의 무결성을 검증할 수 있으므로 빠르고 효율적입니다.
3-2. 단점
- 크기 증가:
- JWT는 헤더와 페이로드, 서명까지 포함하기 때문에 세션 ID보다 크기가 큽니다.
- 네트워크 트래픽에 영향을 줄 수 있습니다.
- 보안 문제:
- JWT는 서명(Signature)을 통해 변조 방지는 가능하지만, 암호화되지 않으므로 페이로드에 포함된 정보는 누구나 볼 수 있습니다.
- 민감한 정보는 JWT에 포함하지 말아야 합니다.
- 토큰 만료:
- 토큰이 만료되기 전까지 유효하므로, 만료된 토큰을 갱신하거나 철회하는 데 관리가 필요합니다(예: 로그아웃 시).
4. JWT의 사용 사례
- 사용자 인증:
- 사용자가 로그인하면 서버가 JWT를 발급하여 클라이언트가 이후 요청에서 인증을 수행할 수 있도록 합니다.
- 권한 부여:
- JWT의 Payload에 사용자의 권한(Role)을 포함하여, 서버가 사용자의 액세스 권한을 결정합니다.
- 다중 플랫폼 지원:
- 모바일, 웹 등 다양한 클라이언트에서 동일한 JWT를 사용할 수 있습니다.
- API 인증:
- RESTful API 또는 GraphQL API에서 클라이언트-서버 간 통신을 인증하는 데 사용됩니다.
5. JWT의 보안 고려 사항
- 비밀 키 관리:
- 서명에 사용되는 비밀 키(secret key)는 철저히 보호되어야 합니다.
- 만료 시간 설정:
exp
(Expiration Time) 클레임을 사용하여 토큰의 유효 기간을 명시적으로 설정합니다.
- HTTPS 사용:
- 토큰 전송 시 HTTPS를 사용하여 데이터의 중간자 공격을 방지합니다.
- 정보 최소화:
- Payload에는 최소한의 정보만 포함하고, 민감한 데이터는 절대 포함하지 않습니다.
- 토큰 철회(Revoke):
- 로그아웃 등 특정 시점에서 토큰을 철회하거나, 서버에서 "블랙리스트"를 관리하여 특정 토큰을 차단합니다.
6. JWT의 실제 예제 (JavaScript 기반)
JWT 생성
const jwt = require('jsonwebtoken');
const payload = {
sub: '1234567890',
name: 'John Doe',
admin: true
};
const secretKey = 'your_secret_key';
const token = jwt.sign(payload, secretKey, { expiresIn: '1h' });
console.log(token);
JWT 검증
try {
const decoded = jwt.verify(token, secretKey);
console.log(decoded);
} catch (err) {
console.error('Invalid token');
}
회고
- 뉴스피드 프로젝트가 내일 종료된다.
모두의 고생이 담긴 결과물이 마무리까지 잘 끝났으면 좋겠다.
- 챌린지반 과제로 위 주제에 대해 공부했는데, 개념은 역시나 너무 어렵다.
본 수업때 들으면서 이해해봐야겠다.
- 발표 마치는날까지 화이팅!!!
그럼이만