Learn how JSON Web Tokens (JWT) works in just a few minutes

Image for post
Image for post

This is a fairly short article to cover the fundamentals of JWT in order to get you quickly started. Learning authentication in general is a challenge most developers struggle with, not because it’s difficult, but there are few concepts to learn such as cookies, sessions, tokens, encoding algorithms and so forth.

It is important to understand that the purpose of using JWT is NOT to hide or obscure data in any way. The reason why JWT are used is to prove that the sent data was actually created by an authentic source

Mikey Stecky-Efantis

Topics we’ll address

  1. What is a JSON Web Token (JWT)?
  2. How it works in practice (4 easy steps)
  3. Let’s create a simple JWT
  4. Summary

1. What is a JSON Web Token (JWT)?

Json Web Token (JWT) is an open standard (RFC 7519) for securely transmitting information between endpoints as JSON object.

The JWT consist of three main parts separated by dots (.).

// JWT high-level representation
header.payload.signature
// How JWT looks
eyJhbGciOBJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImpvaG4gZG9lIiwiaWF0IjoxNGYyMjMyNzI2fQ.NnOv-wHAf59L2WMcDlfNsTThOUY1a0JMFNgJIP67mqU

Let’s describe the three parts that define JWT.

Header

The first part consist of two things; the type of the token which is JWT, and the algorithm being used such as RSA, HMAC, or SHA256. PS! If you don’t define the algorithm, it uses HS256 by default.

{
"alg": "HS256",
"typ": "JWT"
}

Payload

The second part is the actual data, we can also add additional information known as claims which is optional such as the expiration time (exp), subject (sub), or issuer (iss). Notice the claim names are short, that is because JWT is meant to be compact for fast requests.

One would think that is not important, but imagine a site having millions of requests, and for every request a mathematical algorithm is run to grant users access to web resources. It can sure lead to some heavy traffic slowing down the server calls.

PS! Don’t put sensitive data such as password in your payload thus this can easily be decoded.

{
"sub": "2311",
"name": "Mike Tyson",
"admin": true
}

Signature

The last part is the signature which is the sum of the encoded header, the encoded payload, a secret, and lastly the algorithm which is specified in the header.

The signature is the most important part of the JWT structure. The header and payload can easily be decoded, but not the signature. The reason why is because it checks two things; first verify the header and payload has not been altered, and secondly check the private key is valid to make sure the sender is who it is.

let data = base64UrlEncode(header) + "." + base64UrlEncode(payload)// Creates a signature
HMACSHA256(data, secret)
// Signature key
AflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

In short, if either the header, payload or private key changes along the way, the verification process will fail thus the token is not equal to the one that was initially created.

2. How it works in practice (4 easy steps)

The most common approach of authentication is to store the user in a session on the server. A session is a temporary file to make data accessible across pages on a website such as making sure the user can access a web resource. However, with JWT, we don’t need to manage sessions on the server anymore because the server only cares if the incoming request is valid, and comes from the right person.

Here’s four steps showing how JWT works in practice without needing to use the sessions on the server.

  1. User logs in with username and password
  2. If credentials are correct, server creates a signed JWT which says who the user is.
  3. User wants to access home page
  4. Verify the JWT signature is valid, if true, grant access.

3. Let’s create a simple JWT

This is a short example to show how to create a JWT, and also what happens if we try to verify a signature that has exceeded an expiration time (6 seconds).

Here’s the example we’ll cover in details with 3 steps.

const jwt =  require('jsonwebtoken');const private_key = 'pizza1234';
const payload = { username: 'john', email: 'john@gmail.com' };
// Create a JSON Web Token (JWT)
const token = jwt.sign(payload, private_key, {expiresIn: '5s'});
console.log(token);
// After 6s: verify signature (it will fail)
setTimeout(() => {
const data = jwt.verify(token, private_key);
console.log(data);
}, 6000)

1. Setup

const private_key = 'pizza1234';
const payload = { username: 'john', email: 'john@gmail.com' };

Before we can have fun with JWT, we need to install the jsonwebtoken package from npm. Once installed, we import it in our file using require.

Then we create two const variables; the private key and the payload object.

In a real world scenario, the private key may be the RSA private key stored on the server machine, but for now, thanks to our creativity we’ll go for pizza1234.

2. Create a JWT

// Create a JSON Web Token (JWT)
const token = jwt.sign(payload, private_key, {expiresIn: '5s'});
console.log(token);

The way we create a JWT is to use the jwt.sign(payload, secret, optional). With the optional object, we pass the expiration time which is set to 5 seconds.

3. Verify JWT

// After 6s: verify signature 
setTimeout(() => {
const data = jwt.verify(token, private_key);
console.log(data);
}, 6000)

After 6 seconds the function setTimeout(callback, time) tries to verify the token, but fails because the time has exceeded by 1 second. We get TokenExpiredError: jwt expired. To solve this, just extend the expiration time to 1 day like {expiresIn: '1d'}.

Whenever the user wants to access something, we use jwt.verify(token, private_key) to verify the user has access rights. It can be done for every request, most commonly in a middleware.

4. Summary

Once you understand how the JWT works, it makes the job of implementing it a bit easier. If there is one take-way advice here, try JWT as shown in the example above before using it in a real-world app.

In essence, the whole idea of JWT is to create a key which can be used to authorize requests, as mentioned in the intro, it is not for encrypting the data, but verifying the sender and the data has not been altered along the way.

Resources

You can find me on Medium where I publish on a weekly basis. Or you can follow me on Twitter.

P.S. If you enjoyed this article and want more like these, please clap ❤ and share with friends that may need it, it’s good karma.

Software Engineer sharing interesting tech topics

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store