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
와 같이 보임
Header
- 헤더는 일반적으로 두 부분으로 구성
- 사용 중인 서명 알고리즘 (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를 획득하고 사용하는 방법
- 애플리케이션 또는 클라이언트가 인증 서버에 인증을 요청
- 권한이 부여되면 서버는 애플리케이션에 액세스 토큰을 반환
- 애플리케이션은 액세스 토큰을 사용해 보호된 리소스(예: 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
Get Started with JSON Web Tokens
Why header and payload in the JWT token always starts with eyJ