JSON Web Tokens (JWTs) 101
Tags: jwt, webdev, authorisation, authentication
Published: 2021-05-16 13:27:12

---
title: JSON Web Tokens (JWTs) 101
published: true
description: Introduction to JSON Web Tokens
tags: jwt, webdev, authorisation, authentication
//cover_image: https://direct_url_to_image.jpg
---

# JSON Web Tokens (JWT)

To understand the concept of JWT, we need to understand the authentication and authorisation.

- Authentication
- Authorisation
- JWTs

## Authentication

Authentication is a process in which a user is determined if he is exactly who he is claiming to be. For eg. a user "John Smith" requesting for his FB messages needs to be authenticated by the FB server that he is indeed John Smith, not someone impersonating him. 

Username, password, OTP are common ways of authenticating a user.

## Authorisation

John, say, needs to access messages of a group he is part of. Now server needs to verify if John is indeed an admin of the group and he is authorised to view the group's inbox. 

Authorisation is the process of checking for the access privilege of the user. Server typically does this by verifying the user id against the roles mapped to it.

## JSON Web Tokens

JWTs are used to handle both authentication and authorisation. Let us see how JWTs work before we dive into how it is used to ensure authentication and authorisation.

Like the name says, JWTs are JSON format based tokens used in the web. JWTs usually look like `aaaaaaaa.bbbbbbb.ccccccc`. Notice the `.` delimiter between sections. These three sections in a JWT are 
- Header
- Payload
- Signature
respectively. Each section is in JSON format as specified above.

### Header
A JWT header consists of two parts. The type of the token `typ` and the algorithm used to sign this token `alg`. This `alg` section contains an identifier for a hashing algorithm such as `HMAC`, `SHA256` or `RSA`.

A typical header section looks like 

```json
{
    "typ": "JWT",
    "alg": "SHA256"
}
```

### Payload

JWT's payload contains claims related to the token. Claims are basically statements about a specific section of data. Examples of claims in a JWT as `issuer_name`, `creation_time`, `expiration_time` etc. 

The claims are represented by either reserved keywords or custom keywords. The advtange of a reserved keyword is for universal interoperability. As in, any receiver can make a reserved claim mandatory and sender would know what keyword would use without explicit agreement.

Examples of reserved claims are `iss` for issuer, `exp` for expiry date, `sub` for subject. A JWT can contain both reserved claims and custom claims. 


```json
{
    "iss": "server_identifier",
    "sub": "login_auth",
    "exp": "1621177091", // unix epoch for standardization,
    "user_id": "IN876TY34"
}
```

In this example, `user_id` is a custom claim.

Note: Both header and payload are Base64Url encoded.

### Signature

Signature is what provides security to a JWT and prevents tampering of the data. Anyone can see the contents of a JWT payload if it is not encrypted, but any tampering will make the token invalid because tampering of the data changes the signature.

A signature of a JWT is created with the algorithm specified in the header section along with a secret, encoded sections of header and payload. Since signature is created based on the encoded payload, any changes in the payload will invalidate the signature.

Though attacker has access to encoded header, payload and algorithm from the JWT, he won't know the secret.

```json
SHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
```

A JWT after creating these sections look like 
`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InNoYXNoYW5na2EiLCJwYXNzd29yZCI6IjEyMzQ1IiwiaWF0IjoxNTM2MjgwMjM1LCJleHAiOjE1MzYyODAyNjV9.iplar3jWiW8rh1gU1H6pYaPu6-njCfflrP8GLbx9Imw`

Now that we have created a JWT, let us look into how it is used in authentication and authorisation. 


## How to use JWTs ?

JWTs are created during the authentication flow. Once the user logs in with username/password details, a JWT is generated by the server. This JWT is stored by client , usually in local storage, and is sent to server for each subsequent request as part of `Authorisation` header.

`'Authorisation': 'Bearer <jwt>'`

In the payload section of JWT, data related to the authentication and authorisation can be stored which is used by the server to authenticate the user and also verify the user's authorisation for various API access etc. 

#### Example of creating JWT using Node.js

We use a npm package
`npm install jsonwebtoken`

```js
const jwt = require('jsonwebtoken')

 const jwtSecretKey = '<JWT_SECRET_KEY_STORED_AS_ENVIRONMENT_VARIABLE>';
 const data = {
        "time": Date(),
        "iss": "server_identifier",
        "sub": "login_auth",
        "exp": "1621177091", 
        "user_id": "IN876TY34"
    }
   const token = jwt.sign(data, jwtSecretKey);
```

A JWT is not to be confused with a cookie. More discussion into this comparison will be subject of next post. A JWT is usually used to store and transmit authorisation data. 

One downside of using a JWT is all the data is stored in it as claims. Since it is passed to server from client for every request, there is lot of data being transmitted over the network everytime and this only gets worse as more and more data is stored in a JWT.