JWT 구조

BlackBird·2025년 1월 25일

개발자 취업 일지

목록 보기
115/116

면접에서 받았던 질문이였는데 사실 대답은 제대로 못했다.

음 뭔가 좀 본능적이라고 해야될까? 개발을 하면서 흐름이나 어떤 역할을 하는지는 알고 있는데 용어를 정리하면서 설명을 하기가 막막해서 이참에 제대로 알아보는 시간을 가져야겠다고 생각했음.

실제 프로젝트를 진행하면서 성공적으로 구현을 해낸 기술에 대해서 제대로 설명을 못한 것이 아쉬웠다.

여튼 JWT 구조. 파보자.


JWT란?

난 JWT가 단순하게 헤더에 서명을 태워 보내서 사용자를 인증하기 위한 것으로만 알고 있었고 JWT 토큰에는 사용자의 정보가 암호화되어서 담겨있다는 것 정도만 인지하고 있었다. (사실 이거면 사용하는데에는 문제는 없다고 생각하고 있었다..)

정리를 해보자.

  1. JWT는 Json Web Token의 약자이다. 사용자를 식별, 인증을 동시에 처리할 수 있는 토큰 기반의 인증 형식.

  2. 토큰 자체에 사용자의 식별 요소가 포함되어있음.

  3. RESTful과 같이 Stateless(무상태) 환경에서 사용자 데이터를 주고 받는 것이 가능
    -> 사용자와 백엔드의 통신을 최소화 할 수 있음을 뜻함. 왜? 토큰 자체에 식별 요소가 있으니까.

  4. 토큰을 클라이언트에 저장하고, HTTP 헤더에 토큰을 포함시켜서 요청하는 것만으로 데이터 요청과 응답을 받을 수 있음.

정도가 되겠다.

JWT의 구조

내가 대답을 못했던 질문인데,

이미지를 보면 세개로 나눌 수 있다.

  • JWT의 메타데이터를 담고 있는 부분
  • 서명시 사용하는 키(kid), 사용할 타입(typ), 서명 암호화 알고리즘(alg)의 정보가 담겨 있음.
    • 키(kid): 여러 키 중에서 사용할 특정 키를 식별하기 위한 ID.
    • 사용할 타입(typ): 토큰의 타입을 나타내는데 JWT 그 자체라고 생각하면 됨(지금 JWT 토큰공부중이니까..)
    • 서명 암호화 알고리즘(alg): 토큰 서명을 생성하거나 검증할 때 사용하는 암호화 알고리즘을 지정.
      • 서명 암호화 예:
        • HS256: HMAC + SHA-256 (대칭 키 기반)
        • RS256: RSA + SHA-256 (비대칭 키 기반)
        • ES256: ECDSA + SHA-256 (비대칭 키 기반)

Header 예시.

{
  "kid": "abc123",      // 키 식별자
  "typ": "JWT",         // 토큰 타입
  "alg": "HS256"        // 서명 알고리즘
}

Payload

  • 토큰에서 사용할 정보의 조각들인 클레임(Claim)이 담겨 있음 (사용자 권한레벨, 아이디 등의 정보)
  • 클레임(Claim)은 Key/Value 형태로 된 값을 가짐.
  • 저장되는 정보에 따라서 Registered Claims(등록된 클레임), Public Claims(공개 클레임), Private Cliams(비공개 클레임)로 구분됨.
    • 클레임 종류
      • Registered Claims(등록된 클레임)
        • 표준으로 정의된 클레임
        • iss (Issuer): 토큰 발급자
        • sub (Subject): 토큰의 대상 (사용자 ID 등)
        • aud (Audience): 토큰의 수신자
        • exp (Expiration): 토큰 만료 시간
        • iat (Issued At): 토큰 발급 시간
        • nbf (Not Before): 토큰 활성화 시작 시간
      • Public Claims (공개 클레임)
        • 사용자 정의 클레임
        • 충돌을 방지하기 위해 URI 형식으로 네임스페이스를 설정하는 편
      • Private Claims (비공개 클레임)
        • 클라이언트와 서버(발급자와 수신자)간에만 공유되는 사용자 정의 데이터
        • 권한 레벨(roles), ID 등.

Payload 예시

{
  "sub": "123123",  // 사용자 ID
  "name": "철수",   // 사용자 이름
  "admin": false,        // 관리자 여부
  "exp": 720000     // 만료 시간
}

Signature

  • Header 에서 정의한 알고리즘 방식(alg)을 활용
  • Signature(서명)는 JWT의 무결성을 보장하고, 토큰이 변조되지 않았음을 증명하기 위한 것.

Header와 Payload 결합

  • Base64Url로 인코딩된 Header와 Payload를 .으로 연결.
    base64UrlEncode(Header) + "." + base64UrlEncode(Payload)
  • 서명 생성
    • 서버에 저장된 비밀 키(key)와 Header에서 정의한 암호화 알고리즘(alg)을 사용해 위 데이터를 암호화.

    • 일반적인 알고리즘:
      - HS256 (HMAC + SHA-256): 대칭 키 방식
      - RS256 (RSA + SHA-256): 비대칭 키 방식

      Signature = HMACSHA256(
        base64UrlEncode(Header) + "." + base64UrlEncode(Payload),
        secretKey
      )
  • 최종 토큰
    • Header, Payload, Signature를 .으로 연결한 최종 JWT가 생성.

      <Header>.<Payload>.<Signature>

그렇게 되어서 위의 이미지 처럼 구조가 이뤄진다.

디테일하게 파고드니까 이해가 좀 수월하네.

profile
한영신의 벨로그입니다.

0개의 댓글