Stop Guessing: What is a JWT?
Tags: security, jwt, javascript, node
Published: 2020-08-23 20:41:50

# Stop Guessing: What is a JWT?

![A string of english characters separated by dots form a JSON Web Token that has three parts: header, payload and signature.](https://dev-to-uploads.s3.amazonaws.com/i/uoie4izbvw839zxfu9o6.png)

## JSON Web Token (JWT)
A JWT Is an open standard that defines a compact and self-contained way for performing Authentication in REST APIs where information is securely transmitted between both parties as a JSON object.

This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with HMAC algorithm) or a public/private key pair using RSA.

**NOTE 1**: We consider it compact because of its size, it is possible to send it through an URL, POST parameter, or inside an HTTP header. Also due to its size its transmission is fast.
**NOTE 2**: We consider it self-contained because we do not need to query the database more than once, the payload contains all the necessary information about the user.

---
## When to use JWT?
**Authentication**: After the user is signed in, each subsequent request includes the JWT. This allows the user to access routes, services, and resources that require that token.

**Information Exchange**: JWTs are a secure way of transmitting information between parties, because you can be sure that the sender is who they say they are, since they can be signed (possibly by using a public/private key pair). You can also verify that the content has not changed, since the signature is created using the header and the payload.

---
## JWT Structure
A JWT is formed by three parts separated by dots (.): a Header, a Payload, and a Signature. These parts follow this structure: xxxxx.yyyyy.zzzzz.

![The first part of a JWT is the header, the second the payload and the third the signature.](https://dev-to-uploads.s3.amazonaws.com/i/343jnps1u5dn0hi4deoc.png)

### Header
Contains some information that usually include the token type (which is JWT) and the hashing algorithm (such as HMAC, SHA256 or RSA).

Afterwards the JSON containing that Header is Base64Url encoded to form the first part of the JWT.

```
//Example of a Header
{
  "alg": "HS256",
  "typ": "JWT"
}
```
### Payload
Contains the claims that are statements about an entity (usually the user) and additional metadata.

**NOTE**: Can not contain sensible information about a user like password, but it is ok to include user id, name or email.

**Example of claims**: iss (issuer), exp (expiration time), sub (subject), aud (audience), among others.
Afterwards the JSON containing the payload is then Base64Url encoded to form the second part of the JWT.

```
//Example of a Payload
{
  "sub": "0987654321",
  "name": "Jane Doe",
  "admin": true 
}
```
### Signature
Is used to verify that the sender of the JWT is who they claim to be and to ensure that the message was not changed while it was being transmitted.

To create the signature take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign it.

```
//Example of a Signature using the HMAC SHA256 algorithm
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
```

**NOTE**: A simple way to generate a secret is using http://www.md5.cz/ to generate a MD5 hash of a string.
### Uniting the three parts
The output is three Base64 strings separated by dots: an encoded header, an encoded payload and it is signed with a secret. They can be passed in HTML and HTTP environments.

![Shows the jwt.io website where you can play with JWTs by encoding and decoding them. You can choose the hashing algorithm.](https://dev-to-uploads.s3.amazonaws.com/i/1zi8p9d4nw85013plppc.png)

**NOTE**: Go to jwt.io, a website that allows you to decode, verify and generate JWT.

---

## How does a JWT work?
1 - When the user is authenticated by successfully signing in using their credentials, a JWT will be returned.

![Insomnia was used to generate a JWT by passing a http POST request with a body containing the user email and password.](https://dev-to-uploads.s3.amazonaws.com/i/wx8cifob01wrfcg8dker.png)

![Insomnia receives a response that was sent previously. The response contains the JWT and information about the user.](https://dev-to-uploads.s3.amazonaws.com/i/kt6s88dmgp1l35dj7edx.png)

**NOTE**: Keep in mind that tokens are credentials, so you must prevent security issues: do not keep tokens longer than required.

2 - Whenever the user wants to access a protected route, its request should send the JWT, usually in the Authorization header using the Bearer schema: Authorization: Bearer <token>.

![Insomnia sends a request to access a route that requires a JWT (an authenticated user) by including the JWT in the request.](https://dev-to-uploads.s3.amazonaws.com/i/wrjudrz212l324n75jyv.png)

**NOTE**: This authentication mechanism is stateless, because the user state is not saved in the server memory. Instead, the server's protected routes check for a valid JWT in the Authorization header, and only allows the user if this condition is fulfilled. As a result it is not necessary to query the database multiple times as JWTs are self-contained, so it already has all the necessary information.
## Why Should You Use JWT?
- **They are stateless**: Since tokens are self-contained they have all the information that is needed for authentication. This is good for scalability as your server does not have to store session state.
- **They can be generated from anywhere**: Token generation and token verification are decoupled. This allows you to handle the signing of tokens on a separate server.
- **They allow access control**: Within the payload it is possible to specify user roles and permissions. You can also define the resources that the user can access.

## Best Practices
- **Let tokens expire**: When a token is signed it will never expire unless you change the signing key or explicitly set an expiration. This could pose potential issues so it is necessary to have a strategy for expiring and/or revoking tokens.
- **Do not store sensitive data in the payload**: Tokens can be easily decoded, their goal is to protect against manipulation with their signature. So only add the necessary number of claims to the payload to have the best possible performance and security.
- **Be a good magician, do not reveal your secret**: Only reveal the signing key to services that really need it. It should be treated like any other credentials.
- **Utilize HTTPS**: On non-HTTPS connections the requests can be intercepted and tokens compromised more easily.

# Keep in touch
Contact me through my social media. Let's talk about security, authentication and programming in general, be it on [LinkedIn](https://www.linkedin.com/in/stevescruz/) or [GitHub](https://github.com/stevescruz).

Share with us what JWT good practices you advocate for.