JSON Web Tokens

A JSON Web Token (JWT) is a token that can transmit information safely between two entities.

It's digitally signed, which means it's trustworthy. A malicious 3rd party cannot alter it without breaking the signature.

Stateless authentication schemes often use JWT's for authentication.

Anatomy

A JWT has three parts: A header, a payload, and a signature.

Header

The header contains meta-information about the token. Two pieces of information are usually stored here. First, it specifies that it is a JSON web token. The second piece of information is which signing algorithm is used.

Payload

The payload contains the actual information used to authenticate a user. A JWT should contain as little information as possible. Often a single user id is enough to identify a user.

The payload holds information in key/value pairs called claims.

Signature

The signature is used to verify that the token hasn't been altered after it was sent. The signature is necessary because the server needs to trust that a 3rd party hasn't modified it.

The signature itself consists of 2 parts. The first part is the header of the JSON web token converted to base64. The next part is the payload converted to a base64 string. All this is put through a hashing algorithm using a secret.

That means that if the header or payload is modified, the signature will change, and thus it would not pass validation.

Secret

JSON Web Tokens are created and validated on the server. When a server issues a token to the client, they store it safely and send it with each request. When the server receives a request with a JWT, it decodes the token and verifies it.

The server can verify the token using a secret. The secret is used to hash the signature of the JWT. If a malicious 3rd party doesn't know the secret, they cannot decrypt or modify the JWT.

The secret is a long random string of characters.

Claims

The payload of a JWT consists of claims. Claims are key/value pairs. Most systems recognise some reserved claims. Some examples are:

  • Sub (Subject): A value that can identify the user.
  • Iss (Issuer): The domain of the application that has issued the token.
  • Aud (Audience): The domain of the application that uses the token.
  • Exp (Expiration): An expiration timestamp for the token.

It's also possible to create custom claims if a system needs to store other kinds of information in the payload.

Usage

A web application can send a JWT as an HTTP header. The Authorization header is a good choice.

Authorization: Bearer <token>

The server can check for the header on protected routes. If the header is present, the token will be decoded and verified. If it's valid, the request is accepted.

Security

To safely use JWT's, there are few things to keep in mind.

Tokens should never be stored in localStorage or a cookie accessible from the browser. Instead, tokens should be kept in memory or an HTTP cookie.

The secret used to create the signature must only be kept on the server. Preferable, it should be kept in an environment variable and not directly in the codebase.

Authentication scaffolding

Starter kits for Laravel, Vue and React.