본문 바로가기
BackEnd/Server

[JWT] JWT(JSON Web Token) 설명 및 구조

by 푸고배 2021. 8. 21.

 JWT이란? 

JWT(JSON Web Token)은 정보 수신/송신자 간에 정보를 JSON 객체로 안전하게 전송하기 위한 간결하고 Self-contained한 방법을 정의하는 개방형표준(RFC 7519)이다. 이 정보는 디지털 서명되어 있으므로 확인 및 신뢰가 가능하다. JWT는 Secret( HMAC 알고리즘 사용)을 사용 하거나 RSA 또는 ECDSA를 사용하는 공개/개인 키 쌍을 사용하여 서명할 수 있다.

 

JWT를 암호화하여 수신/송신자 간에 기밀도 제공할 수 있지만, 서명된 토큰에 초점을 맞출 것이다. 서명된 토큰은 해당 토큰에 포함된 클레임의 무결성을 확인할 수 있는 반면, 암호화된 토큰은 다른 당사자로부터 해당 클레임을 숨길 수 있다. 공용/개인 키 쌍을 사용하여 토큰에 서명할 때 서명은 개인 키를 보유한 당사자만 서명했음을 증명한다.

 

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

다음은 JSON Web Token이 유용하게 사용되는 몇 가지 시나리오 이다.

  • Authorization(권한부여) : JSON Web Token을 사용하는 가장 일반적인 시나리오로, 사용자가 로그인하면 이후의 각 요청에서는 JWT가 포함되어 사용자가 해당 토큰으로 허용되는 패스, 서비스 및 리소스에 액세스할 수 있다. Single Sign On은 오버헤드가 적고 여러 도메인에서 쉽게 사용할 수 있기 때문에 오늘날 JWT를 널리 사용하는 기능이다.
  • Information Exchange(정보교환) : JSON 웹 토큰은 당사자 간에 정보를 안전하게 전송할 수 있는 좋은 방법이다. 예를 들어 공용/개인 키 쌍을 사용하여 JWT에 서명할 수 있기 때문에 발신인이 자신이 말하는 사용자임을 확인할 수 있다. 또한 서명이 헤더와 페이로드를 사용하여 계산되므로 콘텐츠가 변조되지 않았는지(무결성) 확인할 수도 있다.

 

 JSON Web Token의 구조는? 

간결한 형태의 JSON Web Token은 점( . )으로 구분된 세 부분으로 구성되며 다음과 같다.

  • Header
  • Payload
  • Signature

따라서 JWT는 일반적으로 다음과 같다.

xxxxx[Header].yyyyy[Payload].zzzzz[Signature]

 Header 

헤더는 일반적으로 JWT인 토큰 유형과 HMAC SHA256또는 RSA와 같이 사용 중인 서명 알고리즘의 두 부분으로 구성된다.

예를 들어, 이 JSON은 Base64Url로 인코딩되어 JWT의 첫 번째 부분을 구성한다.

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

 

 Payload 

토큰의 두 번째 부분은 클레임을 포함하는 Payload이다. 클레임은 entity(일반적으로 user) 및 추가 데이터에 대한 설명이다.

청구 유형에는 registered(등록), public(공개), private(비공개) 세 가지가 있다.

  • Registered claims(등록 클레임) : 등록된 클레임들은 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보들을 담기위하여 이름이 이미 정해진 클레임들이다. 등록된 클레임의 사용은 모두 선택적 (optional)이며, 이에 포함된 클레임 이름들은 다음과 같다.
    • iss(issuer) : 토큰 발급자
    • exp(expiration time) : 토큰 만료 시간
    • sub(subject) : 토큰 제목
    • aud(audience) : 토큰 수신자/대상자
    • nbf(Not Before) : 토큰의 활성 날짜
    • iat(issued at): 토큰이 발급된 시간, 토큰의 age가 얼마나 되었는지 판단 가능
    • jti : JWT의 고유 식별자, 주로 중복 처리 방지를 위해 사용, 일회용 토큰에 사용하면 유용
  • Public claims(공개 클레임) : JWT를 사용하는 사용자가 원하는 대로 정의할 수 있다. 그러나 충돌을 방지하려면 IANA JSON Web Token Registry에 정의하거나 충돌 방지 네임스페이스를 포함하는 URI로 정의해야한다.
  • Private Claims(개인 클레임) : 이러한 claim은 이용에 동의하고, Registered claims도, Public claims도 아닌 당사자들 간에 정보를 공유하기 위해 만들어진 custom claim이다. Public claims과는 달리 이름이 중복되어 충돌 가능성이 있다.

payload의 예는 다음과 같으며, Base64Url로 인코딩되어 JSON Web Token의 두 번째 부분을 구성한다.

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
서명된 토큰의 경우 이 정보는 변조로부터 보호되지만 누구나 읽을 수 있다.암호화 되지 않은 경우 JWT의 Payload 또는 Header 요소에 비밀 정보를 넣지 말자

 

 Signature 

서명 부분을 생성하려면 인코딩된 Header, 인코딩된 Payload, 암호, Header에 지정된 알고리즘을 가져와서 서명해야한다.

Header의 인코딩 값과 Data의 인코딩 값을 합친 후 주어진 private key로 해시하여 생성한다.

예를 들어 HMAC SHA256 알고리즘을 사용하려는 경우 서명은 다음과 같은 방식으로 생성된다.

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

서명은 메시지가 도중에 변경되지 않았는지 확인하는데 사용되며, private key로 서명된 토큰의 경우 JWT의 송신자가 누구인지 확인할 수도 있다.

 Putting all together 

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

다음은 이전 Header와 Payload가 인코딩되어 있고 비밀로 서명된 JWT이다.

jwt.io 디버거 를 사용하여 JWT 를 디코딩, 확인 및 생성 할 수 있다 .

 

 

JSON Web Token은 어떻게 작동하는가?

authentication(인증)에서 사용자가 자격 증명을 사용하여 성공적으로 로그인하면 JSON Web Token이 반환된다. 토큰은 자격 증명이므로 보안 문제를 방지하기 위해 세심한 주의르르 기울여야 한다. 일반적으로 토큰을 필요 이상으로 오래 보관해서는 안된다.

 

또한 보안이 취약하기 때문에 민감한 세션 데이터를 브라우저 저장소에 저장해서는 안된다.

 

사용자가 보호된 경로 또는 리소스에 액세스하려고 할 때마다 사용자 에이전트는 일반적으로 Bearer 스키마를 사용하여 Authorization 헤더에서 JWT를 보내야 한다. Header의 내용은 다음과 같아야 한다.

Authorization: Bearer <token>

이는 특정 경우에 stateless(상태 비저장) Authorization 매커니즘일 수 있다. 서버의 보호된 경로가 Authorization header(인증헤더)에서 유효한 JWT를 확인하고, 유효한 JWT가 있는 경우 사용자는 보호된 리소스에 액세스할 수있다. JWT에 필요한 데이터가 포함되어 있는 경우, 데이터베이스를 조회하여 특정 작업을 수행할 필요가 줄어들 수 있지만, 모든 경우가 그런 것은 아니다.

 

토큰이 Authorization header(인증헤더)에서 전송되는 경우 CORS(Cross-Origin Resource Sharing)는 쿠키를 사용하지 않으므로 문제가 되지 않는다.

 

다음 다이어그램은 JWT를 획득하여 API 또는 리소스에 액세스하는 방법을 보여준다.

  1. Application 또는 Client가 Authorization Server에 대한 인증을 요청한다. 이 작업은 다른 인증 흐름 중 하나를 통해 수행된다. 예를 들어, 일반적인 OpenID Connect 호환 Application은 인증 코드 흐름을 사용하여 /oauth/authorizate 엔드포인트를 거친다.
  2. 인증이 부여되면 Authorization Server는 Application에 대한 Access Token을 반환한다.
  3. Application은 Access Token을 사용하여 보호된 리소스(예: API)에 액세스한다.

서명된 토큰을 사용하면, 토큰을 변경할 수 없더라도 토큰에 포함된 모든 정보가 사용자나 다른 사람에게 노출된다.

즉, 토큰에 비밀 정보를 입력해서는 안된다.

 

 JSON Web Token을 사용해야하는 이유는 무엇인가? 

SWT(Simple Web Tokens) 및 SAML(Security Assertion Markup Language Tokens)과 비교할 때 JWT(JSON Web Tokens)의 이점에 대해 이야기해 본다.

 

JSON은 XML보다 덜 장황하기 때문에 인코딩될 때 크기도 작아져 JWT가 SAML보다 더 간결해진다. 따라서 JWT는 HTML 및 HTTP 환경에서 전달하기에 좋은 선택이다.

 

보안 측면에서 SWT는 HMAC 알고리즘을 사용하는 공유 secret로만 대칭적으로 서명할 수 있다. 그러나 JWT 및 SAML 토큰은 서명을 위해 X.509 인증서 형식의 public/private key 쌍을 사용할 수 있다. 모호한 보안 허점을 도입하지 않고 XML 디지털 서명으로 XML에 서명하는 것은 JSON 서명의 단순성과 비교할 때 매우 어렵다.

 

JSON Parser는 객체에 직접 매핑되기 때문에 대부분의 프로그래밍 언어에서 일반적이다. 반대로 XML에는 자연스러운 document-to-object 매핑이 없다. 따라서 SAML보다 JWT로 작업하기가 더 쉽다.

 

사용에 관해서는 JWT가 인터넷 규모로 사용된다. 이는 여러 플랫폼, 특히 모바일에서 JSON Web Token의 클라이언트 측 처리 용이성을 강조한다.

인코딩된 JWT와 인코딩된 SAML 길이 비교

JSON Web Token에 대해 자세히 읽고 이를 사용하여 자체 Application에서 인증을 수행하려면 Auth0에서  JSON 웹 토큰 랜딩 페이지 로 이동하자.

 

참고자료 : 

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

 

 

[JWT] JSON Web Token 소개 및 구조 | VELOPERT.LOG

지난 포스트에서는 토큰 기반 인증 시스템의 기본적인 개념에 대하여 알아보았습니다. 이 포스트를 읽기 전에, 토큰 기반 인증 시스템에 대해서 잘 모르시는 분들은 지난 포스트를 꼭 읽어주세

velopert.com

 

반응형

댓글