Building secure NodeJS APIs with JWTs

Overview

Authentication is a trickier subject today than it was 10 years ago. There are hundreds of potential strategies for securing APIs and ensuring that a user is, in fact, who they say they are. When building or refactoring APIs, developers have to decide what authentication strategy makes sense for their particular product use case. This can be daunting, as choosing the wrong approach can lead to difficulties down the road including data breaches, trouble building integrations, and user experience limitations that plague product development. At BoltSource, we’ve had great success leveraging the generic and flexible stateless authentication mechanism provided by JSON Web Tokens. Most of our engineers have 5+ years of battle hardened experience using JWTs full-stack in large-scale consumer and enterprise grade systems. In this post, we’re going to share what we’ve learned about building APIs with JWTs.

What is a JWT?

JSON Web Token (JWT) is an open standard (RFC 7519), popularized by the good folks at Auth0, that defines a compact and self-contained way for securely transmitting information between parties with an encoded JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret or a public/private key pair.

  1. A payload, which is a Base64Url encoded object that typically contains a set of claims and additional data about the user (such as the user’s primary key).
  2. A signature, which is encoded by passing the secret, the encoded header, and the encoded payload into the signing algorithm and then encoding the output as Base64Url.

Simple-Secret Implementation

Now that we have a good high-level understanding of JWTs, let’s take a look at a basic implementation of JWT-based authentication using NodeJS. To get started, we’ll need to install a few packages:

Tenant Secret Implementation

In the previous example, we went over a very simple implementation of JWT that utilized a single JWT secret that is shared to generate and verify all JWTs. In this example, we are going to build on top of that to implement a more complicated secret management paradigm that we’ve come to call “tenant secrets”. Before we dive into the code, let’s discuss the high level architecture for this approach so that you can better understand the goal.

Next

In our next blog post, I’ll be going into more detail about how to implement a working API complete with tenant-secret JWT authentication, PostgreSQL and Redis integration, and deployment on Kubernetes using Google Kubernetes Engine and Docker. Stay tuned!

Founder & CEO @BoltSourceIO