JSON Web Token (JWT) is an open standard used for securely transmitting information between different parties. It helps to accomodate the integrity of the information being passed by using digital signature. Hence the information can be verified and trusted that nobody has tempered the content after being issued by the authority.
Most commonly it is being used for authorization purpose among different web applications. After the user is logged in, each subsequent request will include the JWT, to identity the user and corresponding claims in order to assign access on the server side. Single Sign On is a feature that widely uses JWT.
JSON Web Token structure
JSON Web Tokens consist of three parts separated by dots (.), which are:
- Header
- Payload
- Signature
A JWT typically looks like the following.
xxxxx.yyyyy.zzzzz
where xxxxx
, yyyyy
and zzzzz
respresents Base64Url encoded values of the header
, payload
, and signature
part of JWT.
Header
Header is the first part of JWON Web Token. It typically consists of two parts: signing algorithm being used for encryption i.e. HMAC SHA256
or RSA
, and the type of the token, which is JWT
.
For example:
{ "alg": "HS256", "typ": "JWT" }
Payload
The second part of the token is the payload, which contains the claims. Claims are additional metadata or information we want to transmit. We define claims as simple key-value pairs. There are three types of claims: registered, public, and private claims.
For example, these are the claims usually we store in JWT:
{ "UserName": "idrees", "given_name": "Muhammad", "family_name": "Idrees", "email": "idrees@test.com" }
The payload is then Base64Url encoded to form the second part of the JSON Web Token.
Signature
Signature will be generated by combining the encoded JWT Header and the encoded JWT Payload, and then sign it using a strong encryption algorithm, such as HMAC SHA-256
or RSA
. A secret key will be used by the server to sign this content, so it will be able to verify existing tokens and sign new ones. Signature's logical calculation looks similar to this code sample:
$encodedContent = base64UrlEncode(header) + "." + base64UrlEncode(payload); $signature = hashHmacSHA256($encodedContent);
To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.
Review
The output is three Base64-URL strings separated by dots, being more compact when compared to XML-based standards such as SAML.
The following shows a JWT that has the header and payload encoded, and the calculated signature.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5NjBiMTExZS04NGQ2LTQxYjAtYmMxNS1lYTFiODU1NjY4ZmQiLCJuYW1laWQiOiIzYWI1ODYyMy0yMTY2LTQwMzktOTA1NS03N2JkZGY5YTYyMWEiLCJVc2VyTmFtZSI6ImlkcmVlcyIsImdpdmVuX25hbWUiOiJNdWhhbW1hZCIsImZhbWlseV9uYW1lIjoiSWRyZWVzIiwiZW1haWwiOiJpZHJlZXNAdGVzdC5jb20iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBZG1pbmlzdHJhdG9yIiwibmJmIjoxNTcxODI4OTQ2LCJleHAiOjE1NzE4NzIxNDYsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6MTY5NjMvIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDoxNjk2My9BcGkvQXV0aCJ9.glPa_uFQrn9wUJt8ZBOMQ64llYjPU98zqwv8Qu56ErU
When decoded, by a tool like jwt.io, you will be able to see the content of this token:
HEADER: ALGORITHM & TOKEN TYPE { "alg": "HS256", "typ": "JWT" } PAYLOAD: DATA { "jti": "960b111e-84d6-41b0-bc15-ea1b855668fd", "nameid": "3ab58623-2166-4039-9055-77bddf9a621a", "UserName": "idrees", "given_name": "Muhammad", "family_name": "Idrees", "email": "idrees@test.com", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Administrator", "nbf": 1571828946, "exp": 1571872146, "iss": "http://localhost:16963/", "aud": "http://localhost:16963/Api/Auth" }
Note that, the header and payload is a Base64Url encoded value, it is still in readable form, so do not put confidential information anywhere in the token content.