Here “typ” is used for identifying the token type which will generally JWT and “alg” is used for identifying the hashing algorithm which is involved in creating a signature for JWT.
In the above token, the Payload is the second part, between the first and second dot(.), which is also in Base64Url encoded format as below.
eyJpc3MiOiJodHRwczovL3ZpdmVra3VtYXIuY29tIiwiaWF0IjoxNTQ0MDM0Mjg3LCJleHAiOjE1
NzU1NzAyODcsImF1ZCI6Ind3dy52aXZla2t1bWFyLmNvbSIsInN1YiI6InZpdmVrQHZpdmVra3
VtYXIuY29tIiwiTmFtZSI6IlZpdmVrIEt1bWFyIiwiUm9sZSI6IkFkbWluIn0
The payload contains the claims. Claims are the statements about an entity, generally user, and also it contains additional metadata.
There are three types of Claims.
- Registered Claims
- Public Claims
- Private Claims
Registered Claims
These are a set of predefined claims which are recommended and we have to use it while creating the token, some of them are very useful while validating the token by another service but it is not mandatory.
Below is the example of registered claims,
- iss (Issuer)
It identifies the principal that issued the JWT. Generally a DNS name.
- sub (Subject)
It identifies the principal that is the subject of the JWT. The subject is unique in the context of the issuer. It is generally user id or email id in the context of the user.
- aud (Audience)
It identifies the recipients that the JWT is intended for. In the general case, the "aud" value is an array of case sensitive strings, each containing a StringOrURI value. In the special case when the JWT has one audience, the "aud" value may be a single case-sensitive string containing a StringOrURI value.
- exp (Expiration Time)
It identifies the expiration time on or after which the JWT is no longer valid.
- nbf (Not Before)
It identifies the time before which the JWT must not be accepted.
- iat (Issued At)
It identifies the time at which the JWT was issued
- jti (JWT ID)
It is a unique identifier for the JWT, basically we can say it is an identity key of each JWT.
Public Claims
These can be defined at will by those using JWTs. However, in order to prevent collisions, any new claim name should either be registered in the IANA "JSON Web Token Claims" registry or a value that contains a Collision-Resistant name. In each case, the definer of the name or value needs to take reasonable precautions to make sure they are in control of the part of the namespace they use to define the claim name.
Examples of collision resistant namespaces include:
Private Claims
These are the custom claims, a producer and consumer are using for sharing the information. These claim names can be any things except registered claims or public claims.
If we decrypt Base64Url of above Payload, then we get JSON like below,
- {
- "iss": "https://vivekkumar.com",
- "iat": 1544034287,
- "exp": 1575570287,
- "aud": "www.vivekkumar.com",
- "sub": "[email protected]",
- "Name": "Vivek Kumar",
- "Role": "Admin"
- }
Signature
In the above token, the Signature is the last part after the second dot(.)
JCiVwlHWrgxZHrdGjGdlMH7rMij2Atd6rw0C7reVnd8
Signature is responsible for validating the JWT.
To create the Signature part, we need the encoded header, the encoded payload, and a secret. Now we can use an algorithm to create a signature. Either we can use one secret key known as symmetric cryptography or we can use Public-key cryptography known as asymmetric cryptography for signing. It’s totally up to us which algorithm we are going to implement to create a signature
Below is some algorithm which is used to create a signature,
- HS256
- HS384
- HS512
- RS256
- RS384
- RS512
- ES256
- ES384
- ES512
- PS256
- PS384
In this above token, we are using HMAC SHA256 algorithm known as HS256 (symmetric key algorithm) so for that, we have to use the following way
- HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
Now we dig it more so that we can understand it in the more easy way.
First, we combine the encoded header and encode payload as below.
- encodedHeaderPayload = base64urlEncode(header) + “.” + base64urlEncode(payload)
Now we use hashing function as per our choice. hashedData = hashFunction( encodedHeaderPayload, secret ) In this example, a secret is a string which we want to pass for encryption. Now the final part is converting the hashedData into base64urlEncode format as below.
- signature = base64urlEncode(hashedData)
So putting all three components together as below
- header + “.” Payload + “." + signature
We can use https://jwt.io to see JWT header and payload information and also we can verify it like below
When to use symmetric key algorithm and asymmetric key algorithm
Symmetric key algorithm
If we want to create a token and want to verify it ourselves, only at that time can we use symmetric key algorithm, which means authentication server and application server are same.
Asymmetric key algorithm
If we want to allow a third party application to verify our token, we can use asymmetric keys and share the public key with the third parties. As public keys cannot be used to sign so that no one can forge a valid token with custom claims. The way we share the public key is up to us.
Example - Google keys at here.
How Do JSON Web Tokens Work
First of all, If a user wants to get a JWT then the user has to provide their credentials as a part of authentication and after successful logs, JWT will be returned.
Now, whenever the user wants to access a protected resource from the server then the user agent sends the JWT generally, it is in Authorization header using the Bearer schema.
The content header looks like below
- Authorization: Bearer <JWT>
JWT is a self-contained way for securing transmitting information between two parties so it’s a stateless authentication mechanism. Generally, it contains all the necessary data so we don’t need to call the database. Mostly we use Role or Scopes in the payload to access the protected resources.
There are many open source libraries to support JWT in most of the languages such as .NET, Java, PHP, Python, Ruby, Go, Scala, Swift, C, C++, JavaScript and etc.
Conclusion
In this article, we got the understanding of JSON Web Tokens (JWT) and its benefits.
We can choose algorithm as a symmetric key algorithm or asymmetric key algorithm as per our requirements.
You can also read other articles on my personal blog
here.
If you have any suggestions or questions, please mention them in the comments section.