BreauTek A Programmers Blog
 

Knowledge Prerequisites

JWT is widely supported with implementations on many different environments and technologies however, fundamental knowledge of JavaScript and networking is assumed in this article.

What is JWT

JWT are JSON Web Tokens. These tokens are bits of information that is tamper-proof, which allows you to use them for authenticating users. The information you store can be guarenteed to be not manipulated by the client, therefore when you receive the token back from the client, it can be safely assumed the data hasn't been changed.

For example, the server can generate a token for the user when logging in and this token can be sent to the client to be stored locally. Whenever the client wants to make an authenticated API request to the server, the client can send the token with the request so the server can identify the user making the request.

JWTs is composed of 3 parts:

A token may look like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Each part is separated by a . character and is base64 encoded.

The first part: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 is the header and when decoded to a pure string, you'll find the following JSON:

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

This tells us this token is using the HS256 encryption algorithm and that the type is a JWT type.

The next part is the payload: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

will produce the following JSON:

{
    "sub": "1234567890",
    "name": "John Doe",
    "iat": 1516239022
}

This is the application data, however there are a few keys that are filled by many JWT implementations such as the iat (Issue At) timestamp and the sub (subject). Most of the JWT provided fields are optional, but it's important to know about them to avoid name collisions.

If they are secure, why can we decrypt them?

Good question! JWT simply ensures that that the generated token hasn't been tampered with. So that a token that is generated by the server can be trusted to be the same contents when it receives that token from the client. It does not encrypt the contents of the payload, so anybody that gains access to the token can still read the data!

The last part is the signature: SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

If you tried to base64 decode this string, you would have ended up with binary jibberish. That's because this is part of a one-way encrypted hash which ensures that the rest of the token hasn't been manipulated when verified by the server with the proper secret.

Visit JWT.io to play with JWT tokens and generations in your browser.

Security

Using JWTs is safe for security applications, however there are a few things to keep in mind. JWT is a open industry standard RFC 7519 for communicating between two parties securely.

If there is still concerns about it's concept, maybe it will help to know that Auth0* makes heavy use of JWT for their business.

When choosing an implementation, I suggest using the JWT.io website for their library list of implementations.

* I have no affilation with Auth0.

It's important to choose a trusted library that is secure.

Needless to say, security doesn't stop at the implementation. For JWTs to be secure, they must be signed with a strong secret. If a secret would ever be leaked or exposed, then anybody could generate tokens that the server deems valid. Additionally the generated tokens should be given to the intended clients only.

JWT tokens are not meant to store sensitive information. They are simply a means to ensure that a message hasn't been tampered with.

This means you can also securely verify a user without making a trip to the database.

Token Lifetime

The example token used earlier had an Issue At (iat) field which contained a timestamp in epoch time. This let us know when the token was created, however this token did not have an expiration date.

This isn't very desirable as this means once a token is generated, it is accepted by the server forever.

A token should be created with an expiration date. When should the token expire? That depends on your use case, but short-lived tokens paired with long one-time used renew tokens is recommended.

The idea is the access token is short lived and only usable for 10-15 minutes before they expire. Once the access token is expired, the client can use the renew token to obtain a new access token. The renew token is a long lived token that can last hours or days, depending on the application requirements.

What information should I store in a token

As discussed above, JWTs can be easily read by anybody who obtains access. This means care should be taken when choosing what to store in the token. Some good candidates are:

Some bad candidates are:

Additionally, these tokens are generally stored in cookies or in an HTTP header and are passed to the server on any authenticated request. Sometimes there are limits to how large the token is, so it's desirable to keep token payload as small as possible. Only include just enough information to identify the user. Afterall, an API can always fulfil the ability to get up-to-date profile details about that user.

To conclude

JSON Web Tokens is an excellent way to efficiently and securely authenticate and identify users when used properly. Personally I use the NodeJS jsonwebtoken module in my projects, developed by Auth0. There is also a @types/jsonwebtoken package for TypeScript users.