JWT는 Json Web Token 의 줄임말이다. RFC 7519 에 명세되어 있는 국제 표준으로써, 통신 양자간의 정보를 JSON 형식을 사용하여 안전하게 전송하기 위한 방법이다. JWT 는 정보가 토큰 자체에 포함된 (Self-Contained) 클레임 (Claim) 기반 토큰이다.
JWT는 Header, Payload, Signature의 3가지 부분으로 나뉘어 있습니다.
JSON 형태인 각 부분 전부 Base64로 인코딩 되어 표현되고 있습니다.
- Base64는 암호화된 문자열이 아닙니다. 같은 문자열에 대하여 항상 같은 인코딩 문자열을 반환 해주는 것입니다.
1) 헤더(Header)
Header 는 두가지의 정보를 가지고 있습니다.
typ : 토큰의 타입을 지정합니다.
타입은 JWT 타입입니다.alg : 해싱 알고리즘을 지정합니다.
- 해싱 알고리즘으로는 보통 HMAC SHA256 혹은 RSA 가 사용되며, 이 알고리즘은, 토큰을 검증 할 때 사용되는 signature 부분에서 사용됩니다.
{ "typ": "JWT", "alg": "HS256" }
2) 정보(Payload)
Payload 부분에는 토큰에 담을 정보가 들어있습니다.
여기에 담는 정보의'조각'을 클레임(claim) 이라고 부르고, Key/Value의 한쌍으로 이루어져있다.
토큰에는 여러개의 클레임들을 넣을 수 있다.
클레임 : 토큰의 정보를 클레임이라고 한다.
클레임의 종류는 세 가지로 나뉜다.
1. 등록 된(registered) 클레임
2. 공개(public) 클레임
3. 비공개(private) 클레임
JWT 토큰에 대한 정보들을 담기 위해 이미 정의된 클레임이다. 7개의 등록된 클레임이 있지만, 모두 선택적이며, 토큰 사이즈를 작게 유지하기 위해 이름을 3글자로 축약되어 있는 것을 확인 할 수 있다.
iss(lssuer)
: 토큰 발급자를 나타낸다.sub(Subject)
: 토큰 제목을 말한다.aud(Audience)
: 토큰 수신자/ 대상자exp(Expiration Time)
: 토큰의 만료시간 / 만료시간이 지난 토큰은 거절해야 한다.nbf(Not Before)
: 이 시간 이전에는 토큰을 처리하지 않아야 함을 의미 한다.iat(Issued At)
: 토큰이 발급된 시간 / 토큰의 age가 얼마나 되었는지 판단 가능jti(JWT ID)
: JWT의 고유 식별자로서, 주로 중복적인 처리를 방지하기 위하여 사용됩니다. 일회용 토큰에 사용하면 유용합니다.{ "sub": "1234567890", ... "nbf": "..." "name": "John Doe", "admin": true }
JWT를 사용하는 사용자가 원하는 대로 정의할 수 있으나 충돌을 방지하려면 IANA JSON Web Token Registry에 정의하거나 충돌 방지 네임스페이스를 포함하는 URI로 정의해야한다.
{ "email": "sample@domain.com", "profile": "http://domain.com/image.png", "http://domain.com/xxx/yyy/is_admin": true }
- 등록된 클레임도아니고, 공개된 클레임들도 아니다.
- 서버와 클라이언트 사이에서만 협의된 클레임이다.
- public과 달리 이름이 중복 되어 충돌 될 가능성이 있다.
{ "user_id": "123456790", "user_age": 25 }
3) 서명(Signature)
인코딩된 header 와 payload 를 점(.)으로 이어 붙인 것을 sha256 알고리즘을 사용하여 HMAC으로 암호화 한다. 이 또한 Base64 로 표현되도록 설정한다.
HMAC (Keyed-hash Message Authentication Code) 는 메시지 인증 코드 (MAC) 의 한 유형으로서 특정 Key 와 함께 특정 Message 를 Hash 값으로 만드는 암호화 방식이다. 공격자로 하여금 레인보우 테이블 기법의 해킹을 어렵게 하기 위해 원문과 함께 비밀키를 더하여 해싱하는 것 이다.
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
상태정보를 서버에서 관리 하지 않아 서버의 부하를 줄일 수 있어 속도가 빠르다.
쿠키를 전달하지 않아도 되므로 쿠키를 사용함으로써 발생하는 취약점이 사라집니다.
JWT 토근의 길이가 길어, Payload의 정보들 인증 요청이 많아지면 네트워크 부하가 심해 느려질 수 있다.
토큰이 클라이언트에 저장 되어 클라이언트의 토큰을 조작 할 수 없다.
보안 JWT 는 기본적으로 Payload 에 대한 정보를 암호화하지 않기 때문에 중요데이터를 넣지 말아야한다.