1532 단어
8 분
쿠키, 세션, JWT

인증과 상태 유지: Cookie, Session, JWT 핵심 정리#

1. 주제 소개#

1.1 웹 애플리케이션의 인증과 상태 유지#

웹은 기본적으로 Stateless(무상태) 프로토콜인 HTTP를 사용함. 따라서 사용자의 로그인 상태를 유지하거나 요청 간 정보를 공유하기 위해 별도의 기술이 필요

  • 인증(Authentication): 사용자가 누구인지 확인하는 절차
  • 상태 유지: 페이지를 이동해도 사용자의 로그인 상태가 끊기지 않도록 하는 기술

1.2 핵심 개념#

  • 쿠키(Cookie): 클라이언트(브라우저) 측 저장 방식
  • 세션(Session): 서버 측 저장 방식
  • JWT(JSON Web Token): 토큰 기반 인증 방식

2.1 개념#

  • 클라이언트(브라우저)에 저장되는 작은 데이터 조각
  • 서버가 응답할 때 Set-Cookie 헤더를 통해 설정함
  • 클라이언트는 이후 요청 시 자동으로 쿠키를 서버로 전송함

2.2 특징#

  • 키-값(key=value) 형태로 저장됨
  • 만료 시간 설정 가능 (expires 또는 max-age)
  • Secure: HTTPS에서만 전송 가능
  • HttpOnly: 자바스크립트에서 접근 불가 (보안 강화)
  • 도메인 및 경로 지정 가능

2.3 예제 (JavaScript)#

// 쿠키 설정
document.cookie = "username=John; expires=Fri, 31 Dec 2024 23:59:59 GMT; path=/"

2.4 보안 문제#

  • XSS 공격: 자바스크립트로 쿠키를 탈취할 수 있음 → HttpOnly 설정으로 방지
  • CSRF 공격: 인증된 쿠키를 악용해 원치 않는 요청을 보낼 수 있음 → CSRF 토큰 사용 필요

3. 세션 (Session)#

3.1 개념#

  • 서버에서 사용자의 정보를 저장하고, 클라이언트에게는 세션 ID만 부여하는 방식
  • 클라이언트는 요청 시 세션 ID를 보내고, 서버는 이를 통해 사용자 정보를 찾음

3.2 특징#

  • 데이터가 서버에 저장되므로 보안성이 높음
  • 일정 시간이 지나면 세션이 만료됨
  • 클라이언트는 의미 없는 세션 ID만 저장하므로 정보 유출 위험이 적음

3.3 동작 방식#

  1. 사용자가 로그인하면 서버에서 세션 ID 생성
  2. 클라이언트의 쿠키에 세션 ID 저장
  3. 이후 요청마다 클라이언트는 세션 ID를 전송
  4. 서버는 세션 저장소에서 ID를 대조해 사용자 정보 조회

3.4 예제 (Express.js)#

const session = require('express-session')
app.use(session({
secret: 'my_secret_key',
resave: false,
saveUninitialized: true,
cookie: { secure: false }
}))
app.get('/', (req, res) => {
req.session.username = "John" // 세션에 데이터 저장
res.send("Session Set!")
})

3.5 단점 및 보안 문제#

  • 세션 탈취(Session Hijacking): 세션 ID를 탈취당하면 해커가 사용자 행세를 할 수 있음
  • 서버 부담: 동시 접속자가 많으면 서버 메모리 사용량이 급증함 (확장성 문제)

4. JWT (JSON Web Token)#

4.1 개념#

  • 토큰 기반 인증 방식
  • 서버에 사용자 정보를 저장하지 않고, 토큰 자체에 암호화된 정보(Payload)를 포함
  • 클라이언트가 토큰을 저장하고 요청할 때마다 헤더에 포함시켜 보냄

4.2 구조 (3부분)#

aaaaa.bbbbb.ccccc 형태

  1. 헤더(Header): 토큰 타입과 암호화 알고리즘 (예: HS256)
  2. 페이로드(Payload): 실제 사용자 정보 (username, 만료 시간 등)
  3. 서명(Signature): 위변조 방지를 위한 서명 값

4.3 예제 (Node.js + jsonwebtoken)#

const jwt = require('jsonwebtoken')
// JWT 생성 (발급)
const token = jwt.sign({ username: "John" }, "my_secret_key", { expiresIn: "1h" })
console.log(token)
// JWT 검증
const decoded = jwt.verify(token, "my_secret_key")
console.log(decoded)

4.4 장점과 단점#

  • ✅ 장점
    • Stateless: 서버에 세션 정보를 저장하지 않아 서버 부담이 적음
    • 확장성: 마이크로서비스(MSA) 환경이나 다중 서버 환경에 적합
    • 다중 플랫폼: 웹, 모바일 앱 등 다양한 클라이언트에서 사용 용이
  • ❌ 단점
    • 토큰 탈취: 한 번 발급된 토큰은 만료 전까지 제어하기 어려움
    • 크기: 페이로드 정보가 많아지면 토큰 크기가 커져 네트워크 비용 증가

5. 세션 vs 쿠키 vs JWT 비교#

구분쿠키 (Cookie)세션 (Session)JWT (Token)
저장 위치클라이언트서버 (메모리/DB)클라이언트
보안성낮음 (탈취/변조 용이)높음 (서버 관리)중간 (서명 포함, 탈취 주의)
서버 부담낮음높음 (데이터 저장 필요)낮음 (Stateless)
주 사용처팝업 설정, 비로그인 장바구니로그인, 민감한 정보 저장API 인증, 앱 인증, MSA

6. 언제 무엇을 사용할까?#

  • 📌 쿠키
    • “오늘 하루 보지 않기” 같은 팝업 설정
    • 비로그인 상태의 장바구니 임시 저장
    • 단순한 사용자 편의 기능
  • 📌 세션
    • 보안이 중요한 웹 애플리케이션의 로그인 관리
    • 사용자가 적거나 단일 서버 환경인 경우
  • 📌 JWT
    • 모바일 앱 또는 SPA(React, Vue) 인증
    • MSA(마이크로서비스) 환경에서 서비스 간 인증
    • 소셜 로그인 (OAuth) 토큰 전달

7. 보안 이슈 & 해결 방법#

  1. XSS (Cross-Site Scripting)
    • 쿠키/토큰을 자바스크립트로 탈취하는 공격
    • 해결: 쿠키 설정 시 HttpOnly 옵션 사용
  2. CSRF (Cross-Site Request Forgery)
    • 사용자의 의지와 무관하게 공격자가 의도한 행위(수정, 삭제 등)를 요청하게 함
    • 해결: CSRF 토큰 사용, Referer 검증
  3. JWT 탈취 위험
    • 토큰이 탈취되면 만료될 때까지 막을 수 없음
    • 해결: Access Token 만료 시간을 짧게(30분) 설정하고, Refresh Token을 함께 사용
  4. 네트워크 도청
    • 데이터가 전송 중에 가로채질 수 있음
    • 해결: 모든 통신에 HTTPS 필수 적용

8. 실제 사례 분석#

  1. 쿠키 기반 자동 로그인: 사용자의 편의를 위해 만료 기간이 긴 암호화된 쿠키 사용
  2. 세션 기반 로그인: 전통적인 은행 사이트, 관공서 사이트 등 높은 보안이 필요한 곳
  3. JWT 기반 API 인증: 카카오/구글 로그인(OAuth 2.0), 넷플릭스 등 멀티 디바이스 환경 서비스
쿠키, 세션, JWT
https://devlog.jpstudy.org/posts/2025/cs/cookie_section_jwt/
저자
SY
게시일
2025-07-22
라이선스
CC BY-NC-ND 4.0