| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- 실무는 공식문서로
- 책으론 원리만
- 공부할 거 넘많다~
- git flow finish
- CSS
- 힘들었던 한주
- Mac
- js
- 차이점
- 백준
- 바닐라JS
- 끝까지 잘 마무리하기
- JavaScript
- jQuery
- HTML
- git flow start
- 다시 홧팅
- Next.js
- javascript30
- api 라우트
- fetch pull 차이
- Main
- freecodecamp
- 서버 컴포넌트
- AJAX
- 개발일지
- TS
- 클라이언트 컴포넌트
- git
- axios
- Today
- Total
다다의 개발일지 6v6
🔐JWT(JSON Web Token) 토큰에 대해 + vs 세션 기반 인증 본문
JWT (JSON Web Token) 토큰이란?
JWT 는 웹 애플리케이션에서 인증 및 정보 교환을 위해 사용하는 토큰이다.
사용자의 로그인 상태를 유지하거나, 정보를 안전하게 주고받는 데 사용된다!
- JWT는 로그인 후 서버가 생성하는 디지털 서명된 토큰으로,
- 사용자가 로그인할 때마다 세션을 유지하지 않고도 신원을 확인할 수 있음
JWT 토큰의 특징
- JSON 형식으로 데이터 저장
- 자체적으로 인증 정보를 포함 (서버가 세션을 저장할 필요 없음 → Stateless -> 보안 강화)
- 디지털 서명 포함 → 변조 불가능
- 주로 로그인 인증(Authentication)에 사용
JWT의 구조 (3가지 부분으로 구성됨)
JWT는 .(점)으로 구분된 3가지 부분으로 이루어져 있음.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJ1c2VySWQiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
1️⃣ Header (헤더)
JWT의 타입과 해싱 알고리즘을 정의
{
"alg": "HS256",
"typ": "JWT"
}
- alg: 사용할 해싱 알고리즘 (예: HS256, RS256)
- typ: 토큰 타입 (JWT)
2️⃣ Payload (페이로드)
사용자 정보(클레임, Claims)를 포함하는 부분
{
"userId": "123",
"role": "admin",
"exp": 1712345678
}
- userId: 사용자 ID
- role: 사용자 역할 (예: admin, user)
- exp: 토큰 만료 시간 (Unix Timestamp)
Payload에는 중요한 정보(비밀번호, 카드번호 등)를 넣으면 안 됨!
Base64 인코딩이므로 쉽게 디코딩 가능 → 보안에 주의해야 함
3️⃣ Signature (서명)
서버가 서명한 정보로 JWT의 무결성을 보장
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret_key
)
- Header + Payload 를 조합해 해시 생성
- 비밀키(Secret Key)로 서명하여 변조 방지
-> 서명이 다르면 토큰이 위변조되었음을 감지할 수 있음
JWT 인증 방식 (로그인 과정)
- 사용자가 로그인 요청 (POST /login)
- 서버가 로그인 정보 확인 후 JWT 생성
- 클라이언트(브라우저, 모바일 등)에 JWT 전달
- 클라이언트가 API 요청 시 JWT를 함께 전송
- 서버는 JWT를 검증하여 요청 허용
이때 JWT는 어디에 저장되어 있을까
JWT는 로그인 후 클라이언트(브라우저, 모바일 앱 등)에 저장됨.
저장 위치는 보안과 편의성에 따라 선택할 수 있으며, 주로 로컬 스토리지(Local Storage), 세션 스토리지(Session Storage), 쿠키(Cookie).
🔍 JWT 저장 위치 3가지
| Local Storage | 브라우저 내장 저장소 (window.localStorage) | 사용이 간편, 브라우저 종료 후에도 유지 | XSS 공격에 취약 |
| Session Storage | 브라우저 내장 저장소 (window.sessionStorage) | 브라우저가 종료되면 자동 삭제 | XSS 공격에 취약 |
| Cookie (HTTPOnly) | 클라이언트-서버 간 자동 전송 | XSS 공격 방어 가능, 보안성 높음 | CSRF 공격 위험 |
1. Local Storage (window.localStorage)
localStorage.setItem("token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...");
const token = localStorage.getItem("token");
✅ 장점: 브라우저 종료 후에도 유지됨
❌ 단점: XSS(크로스 사이트 스크립팅) 공격에 취약 (악성 스크립트가 JWT를 탈취할 수 있음)
❌ 보안 취약점 때문에 권장되지 않음
2. Session Storage (window.sessionStorage)
sessionStorage.setItem("token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...");
const token = sessionStorage.getItem("token");
✅ 장점: 브라우저가 닫히면 자동 삭제됨 → 보안성 Local Storage보다 높음
❌ 단점: XSS 공격에 여전히 취약함
❌ 탭을 닫으면 로그인이 풀릴 수 있음
3. Cookie (document.cookie)
document.cookie = "token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...; Secure; HttpOnly; SameSite=Strict";
✅ 장점:
- HttpOnly 옵션을 사용하면 JavaScript에서 접근 불가능 → XSS 공격 방어 가능
- Secure 옵션을 사용하면 HTTPS에서만 전송
- SameSite=Strict 옵션을 설정하면 CSRF 공격 방어
❌ 단점:
- 기본적으로 CSRF(Cross-Site Request Forgery) 공격에 취약
- 서버에서 쿠키 설정 필요
그럼 어디에 저장하는 게 가장 좋을까?
- 보안이 중요한 경우 → HttpOnly + Secure Cookie (최고의 보안)
- 간단한 토큰 저장이 필요한 경우 → Session Storage (보안은 Local Storage보다 나음)
- 편의성을 중시하는 경우 → Local Storage (하지만 보안 취약!)
추천 방법 JWT + Refresh Token (토큰 갱신)
- JWT는 만료 시간이 지나면 더 이상 유효하지 않음
- 이를 해결하기 위해 Refresh Token을 사용
- Access Token(JWT)은 짧은 유효기간 (예: 15분) 설정
- Refresh Token은 긴 유효기간 (예: 7일~30일) 설정
- JWT 만료 시 Refresh Token으로 새로운 JWT 발급
- Refresh Token도 만료되면 다시 로그인 필요
즉, JWT를 쿠키(HttpOnly, Secure)로 저장하고, Refresh Token을 사용해 Access Token을 갱신하는 방식이 가장 안전함
JWT 사용 과정
1️⃣ 로그인 요청 (JWT 생성)
클라이언트 → 서버에 로그인 요청
POST /login HTTP/1.1
Content-Type: application/json
{
"username": "hong",
"password": "1234"
}
서버 응답 (JWT 발급)
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
2️⃣ API 요청 시 JWT 포함
클라이언트 → 서버에 API 요청 시 JWT를 Authorization 헤더에 포함
GET /profile HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
서버는 JWT를 검증 후 요청을 처리
JWT의 장점
| Stateless (무상태성) | 서버가 세션을 저장할 필요 없음 → 확장성 증가 |
| 빠른 인증 처리 | 세션 조회 없이 토큰만 확인하면 됨 |
| 다양한 플랫폼에서 사용 가능 | 모바일, 웹, 서버 간 인증에 활용 |
| 변조 방지 | 디지털 서명이 포함되어 무결성 보장 |
Stateless가 확장성이 우수한 이유
- 서버가 세션 데이터를 저장하지 않음 → 서버 부담이 적어짐
- 서버 간 상태 공유가 필요 없음 → 여러 서버에서 쉽게 확장 가능
- 로드 밸런서가 어떤 서버로 요청을 보내도 동일한 방식으로 처리 가능
JWT의 단점과 보안 이슈
| Payload가 디코딩 가능 | 중요한 정보(비밀번호 등)를 절대 넣지 말 것 |
| 토큰 탈취 시 보안 위험 | HTTPS 사용 + 짧은 만료 시간 설정 |
| 토큰 크기가 큼 | 헤더 부담이 클 경우 압축 (ex: Brotli) |
| 토큰이 만료되면 갱신 필요 | Refresh Token을 활용 |
JWT vs. 세션 기반 인증
| 서버 저장 필요? | ❌ 없음 (Stateless) | ✅ 있음 (Stateful) |
| 확장성 | ✅ 높음 (서버 부담 적음) | ❌ 낮음 (서버 메모리 부담) |
| 속도 | ✅ 빠름 (DB 조회 불필요) | ❌ 느림 (세션 조회 필요) |
| 보안 | ⚠️ 탈취 시 위험 | ✅ 비교적 안전 |
좀 더 자세히 알아보기
세션이란?
세션(Session) 은 사용자의 로그인 상태와 같은 데이터를 서버가 저장하는 방식.
사용자가 웹사이트에 로그인하면 서버가 사용자를 식별할 수 있도록 데이터를 유지하는 공간이다.
🔹 세션 기반 인증 방식의 동작 과정
- 사용자가 로그인하면 서버에서 세션 ID를 생성
- 해당 세션 ID를 서버에 저장하고, 클라이언트(브라우저)에는 쿠키에 세션 ID 저장
-> 쿠키에 세션 ID를 탈취당하면 똑같이 보안에 취약해서 얘도 쿠키의 HttpOnly, Secure 속성을 사용해 보안 강화 해줘야 함. ( 간단한 보안 처리 ) - 이후 요청에서 클라이언트가 세션 ID를 서버로 전송
- 서버는 세션 ID를 확인하여 사용자를 식별
✅ 장점
- 사용자의 로그인 상태를 서버가 직접 관리 → 보안성이 높음
❌ 단점
- 서버가 세션을 저장해야 하므로 메모리 사용량 증가
- 로드 밸런싱이 어려움 (세션 정보가 특정 서버에만 저장됨)
Stateless란?
Stateless 란 서버가 클라이언트의 상태(로그인 정보 등)를 저장하지 않는 방식
즉, 각 요청은 독립적이며 서버는 요청을 받을 때마다 사용자를 새롭게 인증해야 한다.
🔹 JWT 기반 인증 (Stateless) 과정
- 사용자가 로그인하면 서버가 JWT 토큰을 생성하여 클라이언트에 전달
- 이후 요청에서 클라이언트는 JWT 토큰을 함께 전송
- 서버는 JWT를 검증하고, 내부 데이터(DB)와 비교하여 사용자 인증 수행
✅ 장점
- 서버가 세션을 저장하지 않으므로 확장성이 뛰어남
- 여러 서버가 존재해도 클라이언트가 직접 JWT를 보내므로 부하가 분산됨
- 로드 밸런싱이 쉬워짐
❌ 단점
- JWT 자체가 사용자의 정보(권한, ID 등)를 포함하기 때문에 토큰이 탈취되면 위험
- 토큰의 유효기간이 끝날 때까지 유효 → 강제 로그아웃이 어려움
세션 기반 인증에서는 서버가 사용자의 세션 정보를 직접 저장하기 때문에 부하가 증가함.
대규모 시스템에서는 수많은 사용자의 세션을 관리해야 하므로, 서버의 메모리(RAM)와 저장소(디스크)가 부족해질 가능성이 크다.
-> 반면, JWT 기반 인증(Stateless)은 서버가 세션을 저장할 필요가 없음.
-> 즉, 어떤 서버에서 요청을 받아도 동일하게 처리할 수 있으므로 확장성이 뛰어남.
🔹 예를들어 로드 밸런싱 상황
✅ 세션 기반 인증:
- 사용자가 로그인하면 서버 A에 세션이 저장됨
- 이후 사용자가 요청을 보냈을 때 서버 B가 요청을 처리하면 세션이 없어서 로그인이 풀리는 문제 발생
- 따라서 세션을 공유하기 위해 Sticky Session(한 사용자의 요청을 특정 서버로 고정) 또는 세션 저장소(Redis 등) 사용이 필요
✅ JWT 기반 인증(Stateless):
- 클라이언트가 요청할 때마다 JWT 토큰을 함께 전송
- 서버가 요청을 받을 때마다 토큰을 검증하여 사용자 인증
- 어느 서버에서 요청을 받아도 동일한 방식으로 처리 가능 → 로드 밸런싱이 쉬워지고 확장성이 향상됨
'Computer Science > 네트워크' 카테고리의 다른 글
| 🌐 주소창에 URL을 입력했을 때 일어나는 과정! (1) | 2025.03.10 |
|---|---|
| Axios 에 대해 알아보자! (2) | 2025.02.02 |