Home JWT에 대해 알아보기
Post
Cancel

JWT에 대해 알아보기

JWT란 무엇일까요? 어떻게 사용할 수 있을까요?

JSON Web Token이란?

JSON Web Token (JWT)

  • 당사자 간에 정보를 JSON 객체로 안전하게 전송하기 위한 간결하고 독립적인 방법을 정의하는 개방형 표준(RFC 7519)
  • 이 정보는 디지털 서명이 되어 있기 때문에 검증되고 신뢰할 수 있음
  • JWT는 secret(HMAC 알고리즘 사용) 또는 RSA 또는 ECDSA를 사용하는 public/private 키 쌍을 사용하여 서명할 수 있음
  • 서명된 토큰은 claims의 무결성을 확인할 수 있는 반면, 암호화된 토큰은 다른 당사자로부터 이러한 클레임을 숨김
  • public/private 키 쌍을 사용하여 토큰에 서명하는 경우, 서명은 private 키를 보유한 당사자만이 토큰에 서명했음을 증명함

JSON Web Token은 언제 사용해야 하나요?

Authorization (권한 부여)

  • JSON Web Token을 사용하는 가장 일반적인 시나리오
  • 사용자가 로그인하면 이후의 각 요청에 JWT가 포함되어 사용자가 해당 토큰으로 허용된 경로, 서비스 및 리소스에 액세스할 수 있음
  • Single Sign On은 오버헤드가 적고 여러 도메인에서 쉽게 사용할 수 있기 때문에 오늘날 널리 사용되는 기능임

Information Exchange (정보 교환)

  • JSON Web Token은 당사자 간에 정보를 안전하게 전송할 수 있음
  • 예를 들어 public/private 키 쌍을 사용해 서명할 수 있으므로 발신자가 본인이 맞는지 확인 가능
  • 또한 서명은 헤더와 페이로드를 사용하여 계산되므로 콘텐츠가 변조되지 않았는지 확인할 수도 있음

JSON Web Token 구조

JSON Web Token은 점(.)으로 구분된 세 부분으로 구성

  • Header (헤더)
  • Payload (페이로드)
  • Signature (서명)

JWT는 일반적으로 xxxxx.yyyyy.zzzzz와 같이 보임

  • 헤더는 일반적으로 두 부분으로 구성
  • 사용 중인 서명 알고리즘 (HMAC, SHA256 또는 RSA 등)
  • 토큰의 유형 (JWT)
1
2
3
4
{
  "alg": "HS256",
  "typ": "JWT"
}

Payload

  • 페이로드에는 claims가 포함됨
  • Claims: 엔티티(일반적으로 사용자)와 추가 데이터에 대한 진술
  • claims에는 registered, public, private claims의 세 가지 유형이 있음

Registered claims

  • 유용하고 상호 운용 가능한 claims 세트를 제공하기 위해 필수 사항은 아니지만 권장되는 미리 정의된 claims 세트
  • iss(issuer), exp(expiration time), sub(subject), aud(audience) 등이 있음
  • JWT는 간결해야 하므로 claim 이름은 세 글자만 사용 가능

Public claims

  • JWT를 사용하는 사람이 마음대로 정의할 수 있음
  • 그러나 충돌을 방지하려면 IANA JSON Web Token Registry에 정의하거나 충돌 방지 네임스페이스가 포함된 URI로 정의해야 함

Private claims

  • 사용에 동의한 당사자 간에 정보를 공유하기 위해 만든 사용자 지정 claims
  • registered나 public claims가 아님

페이로드 예시

1
2
3
4
5
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
  • 그런 다음 페이로드는 JSON Web Token의 두 번째 부분을 형성하기 위해 Base64URL로 인코딩됨
  • 서명된 토큰의 경우 이 정보는 변조로부터 보호되지만, 누구나 읽을 수 있다는 점에 유의
  • 암호화되지 않은 경우 JWT의 페이로드 또는 헤더 요소에 비밀 정보를 넣지 않기

Signature

  • 서명 부분을 만드려면 인코딩된 헤더, 인코딩된 페이로드, secret, 헤더에 지정된 알고리즘을 가져와서 서명해야 함
  • 서명은 메시지가 도중에 변경되지 않았는지 확인하는 데 사용
  • private 키로 서명된 토큰의 경우, JWT 발신자가 본인이 맞는지 확인할 수도 있음

HMAC SHA256 알고리즘을 사용하려는 경우, 서명 생성 방식 예시

1
2
3
4
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

모든 것을 합치기

  • 출력은 점으로 구분된 3개의 Base64-URL 문자열
  • HTML 및 HTTP 환경에서 쉽게 전달할 수 있음
  • SAML과 같은 XML 기반 표준과 비교할 때 더 간결함

예시: 위에서 보였던 헤더와 페이로드가 인코딩되어 있고 비밀로 서명된 JWT

1
2
3
4
eyJhbGciOiJIUZI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIi0iIxMjMONTY30DkwIiwibmFtZSI6IkpvaG4
gRG91IiwiaXNTb2NpYWwiOnRydWV9.
4pcPyMD09o1PSyXnrXCjTwXyr4BsezdI1AVTmud2fU4

헤더

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

페이로드

1
{ "sub": "1234567890", "name": "John Doe", "admin": true }

서명

1
2
3
4
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  your-256-bit-secret)

JSON Web Token의 작동 방식

인증(authentication)에서 사용자가 자격 증명(credentials)을 사용하여 로그인에 성공하면 JSON Web Token이 반환됨

토큰은 자격 증명이므로 보안 문제를 방지하기 위해 주의해야 함

  • 일반적으로 토큰을 필요 이상으로 오래 보관해서는 안 됨
  • 보안이 취약한 브라우저 저장소에 민감한 세션 데이터를 저장해서는 안 됨

사용자가 보호된 경로 또는 리소스에 액세스하려고 할 때

  • 그때마다 사용자 에이전트는 일반적으로 Bearer 스키마를 사용하여 권한(Authorization) 헤더에 JWT를 보내야 함
  • 헤더의 내용은 Authorization: Bearer <token>와 같아야 함
  • 이는 경우에 따라 stateless 권한 부여 메커니즘일 수 있음
  • 서버의 보호된 경로(routes)는 유효한 JWT를 확인하여 유효한 경우 사용자가 보호된 리소스에 액세스할 수 있더록 허용
  • JWT에 필요한 데이터가 포함되어 있으면 특정 작업을 위해 DB를 쿼리할 필요성이 줄어들 수 있으나 항상 그런 것은 아님

HTTP 헤더로 JWT 토큰 전송을 전송하는 경우, 토큰이 너무 커지지 않게 주의

  • 일부 서버는 헤더에 8KB 이상을 허용하지 않음
  • 사용자의 모든 권한을 포함하는 등 JWT 토큰에 너무 많은 정보를 포함하려는 경우, Auth0 Fine-Grained Authorization과 같은 대체 솔루션이 필요할 수 있음

API 또는 리소스에 액세스하기 위해 JWT를 획득하고 사용하는 방법

  1. 애플리케이션 또는 클라이언트가 인증 서버에 인증을 요청
  2. 권한이 부여되면 서버는 애플리케이션에 액세스 토큰을 반환
  3. 애플리케이션은 액세스 토큰을 사용해 보호된 리소스(예: API)에 액세스

토큰에 비밀 정보를 넣어서는 안 됨

  • 서명된 토큰을 사용하면 토큰에 포함된 모든 정보가 사용자나 다른 당사자에게 노출되지만 변경할 수 없다는 점에 유의

JSON Web Token을 사용해야 하는 이유

Simple Web Tokens(SWT) 및 Security Assertion Markup Language Tokens(SAML)과 비교할 때 JWT의 이점

JSON은 XML보다 장황하지 않기 때문에 인코딩할 때 크기도 더 작아져 SAML보다 더 컴팩트함

  • JWT는 HTML 및 HTTP 환경에서 전달하기에 좋음

보안 측면에서 SWT는 HMAC 알고리즘을 사용하는 공유 비밀로만 대칭적으로 서명 가능

  • JWT 및 SAML 토큰은 X.509 인증서 형식의 공개/개인 키 쌍을 사용해 서명 가능
  • 애매한 보안 허점 없이 XML 디지털 서명을 사용해 XML에 서명하는 것은 JSON 서명의 단순성에 비하면 매우 어려움

JSON 파서는 객체에 직접 매핑되기 때문의 대부분의 프로그래밍 언어에서 일반적

  • 반대로 XML에는 자연스러운 문서와 객체 간 매핑이 없음
  • 따라서 SAML assertions 보다 JWT로 작업하기가 더 쉬움

사용법과 관련하여 JWT는 인터넷 규모에서 사용됨

  • 이는 여러 플랫폼, 특히 모바일에서 JWT의 클라이언트 측 처리의 용이성을 강조함

참고

Introduction to JSON Web Tokens

JWT - Json Web Token

자바스크립트로 JWT 토큰을 발급하고 검증하기

Get Started with JSON Web Tokens

Why header and payload in the JWT token always starts with eyJ

This post is licensed under CC BY 4.0 by the author.