โ€ข

JSON Web Tokens

By Alex โ€ข 5 minutes read โ€ข

TLDR: https://jwt.io/

Introduction

First, what is Authentication and Authorization?

Authentication is your identity, who you are (login). Authorization is what you can do, your permissions (access control).

Authentication and authorization are independent from each other, however they are often used together to provide an effective user session management.

User Session Management

Now, letโ€™s see how to implement authentication and authorization, and how tokens (JWTs) are useful.

A simple user session management service needs 2 things:

Now, to design a system where all its resources are accessible to everyone is straightforward.

No permission control, no authorization required. Everybody has access to every resource in the system, think of public CDNs.

The difficulties arise when the response from the server is dynamic. Meaning userA logged in should not have access to userBโ€™s data.

Please understand, since http is a stateless protocol the server wonโ€™t remember from whom the request is coming from.

To fix that, we need some sort of information (unique token) with each request.

Using this token the server could identify the user.

There are two methods in which web applications manage and remember users (sessions):

  1. ๐—ฆ๐—ฒ๐˜€๐˜€๐—ถ๐—ผ๐—ป ๐—ฏ๐—ฎ๐˜€๐—ฒ๐—ฑ
  2. ๐—ง๐—ผ๐—ธ๐—ฒ๐—ป ๐—ฏ๐—ฎ๐˜€๐—ฒ๐—ฑ

๐—ฆ๐—ฒ๐˜€๐˜€๐—ถ๐—ผ๐—ป ๐—ฏ๐—ฎ๐˜€๐—ฒ๐—ฑ

  1. When you authenticate, the server creates a session and keeps track of it itself.

  2. The server creates a session_id to associate with that session and gives it back to client.

  3. Think of it as a reference token, holds a reference to user state on the server.

  4. For the subsequent requests the client passes this session_id to the server as a part of every requests.

  5. The most common approach is to save the session_id in an http cookie.

๐—ง๐—ผ๐—ธ๐—ฒ๐—ป ๐—ฏ๐—ฎ๐˜€๐—ฒ๐—ฑ

  1. Server gives the user the details itself.

  2. Server encrypts entire user details in the form of a single JSON token.

  3. The server doesnโ€™t have to remember anything,

  4. itโ€™s the clientโ€™s responsibility to get these details every time it makes the requests.

  5. Think of it as value token, it contains the entire user info.

Both the methods have its own advantages and disadvantages, and weโ€™ll discuss that in a separate post.

The token standard

For the purpose of this post, your focus should be on the token.

A token simply put is a string of random characters.

But whatโ€™s so special about a JWT token?

The internet experts got together and drafted a neat way of token generation for data sharing on the internet.

That open standard is called RFC7519.

RFC7519 standard simply dictates:

In our token based method, JWT is the token, it follows the RFC7519 standard.

The JSON Web Token (JWT)

Although, JWT is commonly used for managing authorization.

The idea behind JWT is to define a standard way between two parties to communicate information securely.

Letโ€™s understand JWT and how JWT is the magic pill for almost all authorization problems.

Data structure

First, a JWT has a strictly defined structure to represent your data.

A JWT token structure contains three parts, each part is separated by a comma.

๐—›๐—˜๐—”๐——๐—˜๐—ฅ.๐—ฃ๐—”๐—ฌ๐—Ÿ๐—ข๐—”๐——.๐—ฆ๐—œ๐—š๐—ก๐—”๐—ง๐—จ๐—ฅ๐—˜

here is a table with header, payload, signature:

HeaderPayloadSignature
{"alg": "HS256", "typ": "JWT"}{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

Example:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

By now you wouldโ€™ve understood that, a token is an important piece of information.

And, if a malicious user gets access to your JWT, they can impersonate you.

But token hijacking is not the problem what JWT solves. A JWT token simply ensures that, your data in not tempered. To temper the data, youโ€™ll need the secret_key.

All this is achieved using the signature part of the token.

๐˜€๐—ถ๐—ด๐—ป๐—ฎ๐˜๐˜‚๐—ฟ๐—ฒ = ๐—›๐—˜๐—”๐——๐—˜๐—ฅ + ๐—ฃ๐—”๐—ฌ๐—Ÿ๐—ข๐—”๐—— + ๐—ฎ_๐˜€๐—ฒ๐—ฐ๐—ฟ๐—ฒ๐˜_๐—ธ๐—ฒ๐˜†

Anyone who is in possession of this key can generate a new token with a valid signature.

Most commonly used crypto algorithms used for generating signatures are

Few other characteristics of a JWT token is that,

Compact because itโ€™s just a simple string. It can be easily send/receive via URL, post, http headers etc. This also helps in faster transfer.

Self contained because, this encoded string contains all the required info about the user.

Fast because since youโ€™ve all the info available in the token. You can avoid making user details query to the database more than once.

Role based authorization using JWT

Here we briefly discuss how JWT can be used for role based authorization.

Role-based access control allows you to set granular access to your site, or to specific pages, data, or features.

When you use an authentication provider that supports JWT, your site visitors log in to your site using the provider service, and the service returns an encrypted JWT with user data.

For example, you can set specific roles for people in a specific GitHub organization, or with a specific company email.

The token payload has a required exp (expiration) field, while other fields are optional. The value of exp should be a time/date in the future using the Unix Epoch time format.

You can add any new structure to the token payload for your application. For example, you can add a roles field in an app_metadata object in the payload, so that your application can check the roles assigned to that specific user.

For example, a JWT payload might look like this:

{
  "id": "some id",
  "exp": 1602522810,
  "app_metadata": {
    "authorization": {
      "roles": ["admin","editor"]
    }
  }
  "iat": 1607022935
}

Once youโ€™ve set up a method for writing and reading user roles in app_metadata, you can leverage these roles to control access to various parts of your site, features, or data. The method of controlโ€”whether from the frontend via a CDN or the backendโ€”depends largely on the nature of the content and the level of security required.

For static content restrictions, geographical access rules, or improved performance, you might opt for frontend access control through a CDN. However, remember that it offers limited security and is not suitable for sensitive data or complex operations.

On the other hand, backend access control is paramount when dealing with sensitive or user-specific data, dynamic content, complex logic, or database operations. Itโ€™s the most secure and flexible approach to access control.

Regardless of the chosen method, always remember the golden rule: never rely solely on frontend security. Any critical or sensitive access control should always be enforced at the backend level.

References