In this article we will learn the fundamentals of a JWT token is and how we can benefit from it for authenticating communications between two parties, all of this using vanilla NodeJS and javascript.

JWT is an abbreviation for JSON Web Token, which is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS). ~ IETF

Urggh! What?

Simply put, JWT token is a string we pass in the header or url while making a network request to pass data safely and make sure it hasn’t been tampered with.

Example: www.example.com/private/?token=xxxxx.yyyyy.zzzzz

You might be wondering what’s with the token format! JWT tokens consists of three parts separated by dots ( . ) which are:

1
header.payload.signature

Let’s see the differents parts of a JWT token in details.

1. Header

The header typically consists of two parts: the type of the token, which is JWT, and the hashing algorithm being used, such as HMAC SHA256 or RSA.

1
{
2
"alg": "HS256",
3
"typ": "JWT"
4
}

Then, this JSON is Base64Url encoded to form the first part of the JWT.

1
"use strict";
2
3
var header = { alg: "HS256", typ: "JWT" };
4
var enc_header = Buffer.from(JSON.stringify(header)).toString("base64");
5
// ► "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"

2. Payload

The second part of the token is the payload, which contains the claims. Claims are predefined keys and their values. There are three types of claims: registered, public, and private claims.

1
{
2
"exp": "2019-02-14",
3
"message": "roses are red"
4
}

The payload is then Base64Url encoded to form the second part of the JSON Web Token.

1
"use strict";
2
3
var payload = { exp: "2019-02-14", message: "roses are red" };
4
var enc_payload = Buffer.from(JSON.stringify(payload)).toString("base64");
5
// ► eyJleHAiOiIyMDE5LTAyLTE0IiwibmFtZSI6IkpvaG4gRG9lIn0

3. Signature

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. Too good for us that NodeJS comes with the immensely powerful Crypto library out of the box which we will use in our example.

1
"use strict";
2
const crypto = require("crypto");
3
var jwt_secret = "secret";
4
// enc_header and enc_payload are computed earlier
5
var signature = crypto
6
.createHmac("sha256", jwt_secret)
7
.update(enc_header + "." + enc_payload)
8
.digest("base64");
9
// ► 6C46KAaZGp6RjbSqGllfdQF7g8vXCp02NTSrz-PzeoI

The signature is used to verify that the sender of the JWT is who it says it is and to ensure that the message wasn’t changed along the way.

The final JWT token looks like this

1
var token = `${enc_header}.${enc_payload}.${signature}`;
2
// ► eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIyMDE5LTAyLTE0IiwibWVzc2FnZSI6InJvc2VzIGFyZSByZWQifQ.0u-mkgLo5479CPjJJ4mXCwn2RW4dFT12fiYiopRWsZw

Something important to remember here is that JWT tokens are used for authentication and not encryption, so even without knowing the secret key, someone can read your header and payload data.

But upon receiving the token you can sign the header and payload again with your secret key and compare it with the received signature to detect tampering of token or the message.

A good place to start will be by going to this and play around with the the token we just generated above.

Hi! I’m @Siwalik! If you liked this article, follow me on twitter to know about my latest tech expeditions and side projects! 🙌