[Auth] JSON Web Token(JWT) 이해하기

이영재·2025년 4월 28일
2

Basis

목록 보기
2/4
post-thumbnail

0. 들어가며

최근 면접에서 JWT 관련 질문을 받았다.
평소 익숙하게 사용해왔기에 당연히 설명할 수 있을 거라 생각했지만, 막상 질문을 받으니 개념이 모호하게 떠올라 당황해서 JWT 기본 구조만 설명하고 제대로 답변하지 못했었음.
이 경험을 계기로 JWT에 대해 제대로 정리해보자.

1. JWT란 무엇인가? (핵심 개념)

1.1 JWT(=JSON Web Token)가 무엇인가

JWT란 JSON Web Token의 줄임말이며, JSON 객체 형태로 당사자 간에 정보를 안전하게 전송하는 간결고 독립적인 방식이다. 또한 이 정보는 디지털 서명이 되어있으므로 검증 및 신뢰가 가능하다. HMAC 알고리즘 또는 RSA 또는 ECDSA를 사용해서 공개키/개인키 쌍을 이용하여 서명이 가능.

  • 디지털 서명을 이용해 검증 및 신뢰가 가능
  • JWT 자체 암호화를 제공하지 않는다.
    • 암호화된 JWT도 있긴하다. -> JWE (JSON Web Encryption)

1.2 어디서, 왜 사용하는지

JSON 웹 토큰이 유용한 몇 가지 시나리오는 다음과 같다

  • 권한 부여(가장 일반적)
    • 사용자가 로그인하면 이후의 모든 요청에 JWT가 포함되어 사용자가 해당 토큰으로 허용된 경로, 서비스 및 리소스에 접근이 가능.
    • SSO (Single Sign-On) 방식 : 한 번 로그인 → 여러 시스템 공유 → 인증 관리 비용 감소
      • 추가적인 인증/세션 관리 작업이 줄어든다.
  • 정보 교환
    • 데이터를 안전하게 교환하기 좋은 방식이다.
    • 서명을 이용하여 콘텐츠의 변조와 발신자의 신원 확인이 가능하다.

1.3 "세션 방식 인증"과 비교

세션 방식

  • 사용자가 로그인에 성공하면, 서버는 세션 ID를 발급.
  • 이 세션 ID를 서버 메모리(RAM)나 별도 저장소(Redis 등)에 저장하고,
  • 클라이언트(브라우저)는 이 세션 ID를 쿠키 등에 저장해 요청마다 전송.
  • 서버는 요청이 올 때마다 세션 ID를 조회해 "이 사용자가 누구인지"를 확인한다.

JWT 방식

  • 사용자가 로그인에 성공하면, 서버는 JWT(토큰) 를 발급.
  • JWT 안에는 사용자의 정보(Claim)와 위변조 방지를 위한 서명이 포함.
  • 클라이언트는 이 토큰을 보관(주로 LocalStorage, SessionStorage, Cookie)하고,
  • 요청마다 Authorization 헤더에 JWT를 담아 서버로 보낸다.
  • 서버는 저장된 세션 없이, JWT 자체를 검증해서 인증.

차이점

JWT는 서버에 세션을 저장하지 않고 토큰 자체를 검증해 인증하는 Stateless 방식이고, 쿠키 세션은 서버에 사용자 정보를 저장하고 세션 ID로 인증하는 Stateful 방식이다. JWT는 확장성과 분산 서버 환경에 유리하고, 세션은 보안과 관리 측면에서 단순한 구조를 가진다.

1.4 JWT의 구조 (Header, Payload, Signature)

JSON 웹 토큰은 간결한 형태로 점( .)으로 구분된 세 부분으로 구성된다. 각 부분은 다음과 같다.

헤더 : 일반적으로 토큰의 유형(JWT)과 서명 알고리즘(RSA, SHA256 등)으로 구성된다.

{
  "alg": "HS256",
  "typ": "JWT"
}

그런 다음, 이 JSON은 Base64Url 로 인코딩되어 JWT의 첫 번째 부분을 형성

페이로드 : 클레임은 엔터티와 추가 데이터에 대한 설명

  • 클레임 엔티티 : 누구에 대한 어떤 사실을 주장(claim)하는 것(일반적으로 사용자)
  • ex) 사용자의 id, 사용자 email, 사용자 role(권한), 발급 시각, 만료 시각, 발급자(issuer) 정보 등
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

마침표(.)로 구분하고, 마찬가지로 JSON은 Base64Url 로 인코딩

서명 : Header와 Payload의 무결성과 인증을 보장하는 디지털 서명

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

마찬가지로 JSON은 Base64Url 로 인코딩

모두 함께 모으기
이전 헤더와 페이로드가 인코딩되고 비밀로 서명된 JWT 이다.

2. JSON 웹 토큰은 어떻게 작동하나

1. 사용자 로그인 및 토큰 발급

  • 사용자가 아이디와 비밀번호 같은 자격 증명(credentials) 을 서버에 제출합니다.
  • 서버는 인증에 성공하면 JWT(Json Web Token) 를 발급합니다.
  • 이 JWT는 사용자의 인증 상태를 나타내는 자격 증명 역할을 합니다.

이 토큰 자체가 사용자의 로그인 인증을 대체한다.

2. 클라이언트가 토큰 저장

  • 클라이언트(브라우저, 앱 등)는 발급받은 JWT를 저장소(LocalStorage, SessionStorage, Cookie 등) 에 보관
  • 보안상, 민감한 세션 데이터는 브라우저 저장소에 직접 저장하지 않는 것이 좋다.

3. 보호된 리소스 접근 시 토큰 전송

  • 사용자가 보호된 API나 페이지에 접근할 때마다,
  • 클라이언트는 HTTP 요청의 Authorization 헤더에 JWT를 담아 보낸다.
Authorization: Bearer <token>
  • 서버는 이 Authorization 헤더를 읽고 JWT를 검증

4. 서버에서 토큰 검증

  • 서버는 JWT의 서명(Signature) 을 확인하여,
    • 토큰이 변조되지 않았는지
    • 발급자가 신뢰할 수 있는지 를 검증

이 과정을 통해 서버는 별도의 세션 저장 없이 사용자를 식별한다, (Stateless 인증)

5. 요청 처리 및 리소스 반환

  • 토큰이 유효하면 서버는 요청한 리소스(API 응답 등)를 반환
  • 만약 토큰이 유효하지 않거나 만료되었다면, 서버는 401 Unauthorized 응답을 반환

마무리

사실 그동안 쿠키 세션 방식과 JWT 방식을 대략적으로만 알고 넘어갔었고, 프로젝트에서도 JWT를 사용했지만... 왜 이 방식을 선택했는지, 쿠키 세션 방식과 어떤 차이가 있는지 누군가에게 명확히 설명할 정도로 정리가 되어 있지는 않았다.

기술을 단순히 사용하는 것에 그치지 않고, "왜 이 기술을 선택했는가?", "어떤 상황에 더 적합한가?" 를 고민하며, 설명할 수 있는 수준으로 정리하는 게 중요하다는 걸 다시 한 번 느꼈다.

0개의 댓글