A JSON Web Token (JWT) is a compact, URL-safe way of representing claims that can be exchanged between parties.
All JWTs consist of a header and payload, which are JSON hashes. These objects are stringified and Base64-encoded. The encoded header and payload are combined with a digital signature (JWS), and all three components are concatenated with "." (period).
From Section 9 of JSON Web Encryption specification (RFC 7516):
The JOSE Header for a JWS can be distinguished from the JOSE Header for a JWE by examining the "alg" (algorithm) Header Parameter value. If the value represents a digital signature or MAC algorithm, or is the value "none", it is for a JWS; if it represents a Key Encryption, Key Wrapping, Direct Key Agreement, Key Agreement with Key Wrapping, or Direct Encryption algorithm, it is for a JWE. (Extracting the "alg" value to examine is straightforward when using the JWS Compact Serialization or the JWE Compact Serialization and may be more difficult when using the JWS JSON Serialization or the JWE JSON Serialization.)
And
The JOSE Header for a JWS can also be distinguished from the JOSE Header for a JWE by determining whether an "enc" (encryption algorithm) member exists. If the "enc" member exists, it is a JWE; otherwise, it is a JWS.
{
"alg": "HS256"
}
{
"alg":"RSA1_5",
"enc":"A256GCM",
"iv":"__79_Pv6-fg",
"x5t":"7noOPq-hJ1_hCnvWh6IeYI2w9Q0"
}
JSON Web Encryption (JWE) represents encrypted content using JavaScript Object Notation (JSON) based data structures. It defines a way to encrypt your claims data so that only intended receiver can read the information present in a token.
In the JWE JSON Serialization, a JWE is represented as a JSON object containing some or all of these eight members:
"protected", with the value BASE64URL(UTF8(JWE Protected Header))
"unprotected", with the value JWE Shared Unprotected Header
"header", with the value JWE Per-Recipient Unprotected Header
"encrypted_key", with the value BASE64URL(JWE Encrypted Key)
"iv", with the value BASE64URL(JWE Initialization Vector)
"ciphertext", with the value BASE64URL(JWE Ciphertext)
"tag", with the value BASE64URL(JWE Authentication Tag)
"aad", with the value BASE64URL(JWE AAD)
The six base64url-encoded result strings and the two unprotected JSON object values are represented as members within a JSON object.
Example JWE
The following example JWE Header declares that:
{
"alg":"RSA1_5",
"enc":"A256GCM",
"iv":"__79_Pv6-fg",
"x5t":"7noOPq-hJ1_hCnvWh6IeYI2w9Q0"
}
Base64url encoding the bytes of the UTF-8 representation of the JWE Header yields this Encoded JWE Header value (with line breaks for display purposes only):
eyJhbGciOiJSU0ExXzUiLA0KICJlbmMiOiJBMjU2R0NNIiwNCiAiaXYiOiJfXzc5
X1B2Ni1mZyIsDQogIng1dCI6Ijdub09QcS1oSjFfaENudldoNkllWUkydzlRMCJ
Read JSON Web Encryption specification (RFC 7516) for more information
A signed JWT includes a Base64 Url Safe encoded signature as the third component. The algorithm used to generate the signature is indicated in the header.
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
.eyJzdWIiOiJKb2huIERvZSIsImFkbWluIjp0cnVlLCJpYXQiOjE0NzAzNTM5OTQsImV4cCI6MTQ3MDM1NzYyNywianRpIjoiNmU0MDRiYTgtZjg4NS00ZDVmLWJmYTItZTNmNWEwODM4MGE0In0
.7CfBdVP4uKsb0cogYepCvMLm8rcpjBYW1XZzA-a5e44
{
"typ": "JWT",
"alg": "HS256"
}
This JWT was signed with the HMAC-SHA256 algorithm, hence alg: HS256
.
{
"sub": "John Doe",
"admin": true,
"iat": 1470353994,
"exp": 1470357627,
"jti": "6e404ba8-f885-4d5f-bfa2-e3f5a08380a4"
}
This JWT can be verified with the UTF-8 secret notsosecret
.
An unsigned JWT has the header value alg: none
and an empty JWS (signature) component:
eyJhbGciOiJub25lIn0
.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
.
The trailing dot indicates that the signature is empty.
{
"alg": "none"
}
{
"iss": "joe",
"exp": 1300819380,
"http://example.com/is_root": true
}
The JWT RFC stablish three classes of claims:
Registered claims like sub
, iss
, exp
or nbf
Public claims with public names or names registered by IANA which contain values that should be unique like email
, address
or phone_number
. See full list
Private claims to use in your own context and values can collision
None of these claims are mandatory
A JWT is self-contained and should avoid use the server session providing the necessary data to perform the authentication (no need of server storage and database access). Therefore, role
or permissions
info can be included in private claims of JWT.
The following Claim Names are registered in the IANA "JSON Web Token Claims" registry established by Section 10.1.
iss
(issuer): identifies the principal that issued the JWT.sub
(subject): identifies the principal that is the subject of the JWT. Must be uniqueaud
(audience): identifies the recipients that the JWT is intended for (array of strings/uri)exp
(expiration time): identifies the expiration time (UTC Unix) after which you must no longer accept this token. It should be after the issued-at time.nbf
(not before): identifies the UTC Unix time before which the JWT must not be acceptediat
(issued at): identifies the UTC Unix time at which the JWT was issuedjti
(JWT ID): provides a unique identifier for the JWT.{
"iss": "stackoverflow",
"sub": "joe",
"aud": ["all"],
"iat": 1300819370,
"exp": 1300819380,
"jti": "3F2504E0-4F89-11D3-9A0C-0305E82C3301"
"context": {
"user": {
"key": "joe",
"displayName": "Joe Smith"
},
"roles":["admin","finaluser"]
}
}