close icon
SDK

Introducing the OAuth 2.0 Express SDK for Protecting APIs with JWT Bearer Tokens

Learn how the OAuth 2.0 Express SDK released by Auth0 makes protecting your Express API easier.

March 24, 2022

Auth0 has released express-oauth2-jwt-bearer, a new Express SDK that makes it super easy to protect APIs with JWT Bearer Tokens. Let's take an overview of its features.

Why a New Express SDK?

Auth0’s previous advice for protecting Express APIs was with a combination of three SDKs: express-jwt, express-jwt-authz, and jwks-rsa. And whilst these work well and are popular SDKs, we felt the developer experience could be improved.

We first wanted to simplify the process of protecting an Express API by reducing the number of dependencies from three to one. This also reduces the install size from ~2 MB to ~500 KB. You can see the benefit by comparing our QuickStart before and after implementing the new SDK, as shown in the following screenshot:

SDK code lines comparison

We also wanted to teach the developer community how to protect their APIs with authorization standards like OAuth2.0 rather than a collection of libraries representing token formats, algorithms, and industry abbreviations (jwt, jwks, rsa, and authz).

This is why the project's first incarnation, express-oauth2-bearer, was released experimentally to support our excellent Identity Labs series (express-oauth2-bearer will now be deprecated in favor of express-oauth2-jwt-bearer).

The Role of Standards

express-oauth2-jwt-bearer protects Express APIs using a combination of the well-established OAuth2 Bearer Token Usage spec and the new specification of JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens.

While there’s always been a clear path for developers to acquire an Access Token from a request using the Bearer Token Usage spec, they’ve relied on best practice and industry convention when determining how to verify their authenticity.

With JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens spec, they are able to leverage new standards to consume Access Token JWTs in an interoperable manner. express-oauth2-jwt-bearer partially implements the JWT Profile for OAuth 2.0 Access Tokens specification. It implements the full specification when you enable the strict option. Also, it is deeply customizable so that you can use it across a broad range of Identity Providers.

Protect an Express API with JWT Bearer Tokens

express-oauth2-jwt-bearer uses a similar mechanism to OpenID Connect Discovery to configure itself, so it’s easy to set up with minimal effort. In just a few lines of code, you can easily add it to your API to protect it with Access Tokens issued by Auth0, for example.

To easily protect your Express API with Auth0, start by installing the SDK using npm or yarn, as in the following example:

npm install express-oauth2-jwt-bearer

You can initialize the SDK in code or via environment variables. For the latter, the minimal .env file would look like the following:

ISSUER_BASE_URL=https://<YOUR_TENANT>.auth0.com
AUDIENCE=<YOUR_API_IDENTIFIER>

Replace <YOUR_TENANT> and <YOUR_API_IDENTIFIER> with the values of your Auth0 tenant name and API identifier that you’ll find in the Auth0 Dashboard.

Then add the express-oauth2-jwt-bearer middleware to your API like so:

const express = require('express');
const { auth } = require('express-oauth2-jwt-bearer');
require('dotenv').config(); // Load the .env variables

const app = express();
app.use(auth());

app.get('/api/private', (req, res) => {
  res.json({ message: `Hello ${req.auth.payload.sub}!` });
});

app.listen(3000, () => console.log('listening at http://localhost:3000'))

You can then start your API and test it using curl:

curl http://localhost:3000/api/private \
--header 'Authorization: Bearer ${YOUR_JWT_ACCESS_TOKEN}'

If you’re wondering where to get an Access Token from, you can get one for testing purposes from the Test tab of your API configuration in the Auth0 Dashboard, as shown in the following picture:

Copy access token from Auth0 Dashboard

Check out express-openid-connect to see an example of how to programmatically obtain an Access Token to call external APIs.

Checking for Required Scopes

If you want to additionally check the Access Token’s scopes for a specific route you can use the requiredScopes middleware, as shown below:

const express = require('express');
const { auth, requiredScopes } = require('express-oauth2-jwt-bearer');
require('dotenv').config();

const app = express();
const checkJwt = auth();

app.get('/api/private-scoped', checkJwt, requiredScopes('read:msg'), (req, res) => {
  res.json({
    message: 'You need to be authenticated and have a scope of read:messages to see this.'
  });
});

You can also check custom claims in the Access Token using claimCheck, claimEquals, and claimIncludes (see the docs for the full API).

Under the Hood

express-oauth2-jwt-bearer is a small Express wrapper around two framework agnostic packages:

The following diagram shows the dependencies among these packages:

OAuth2 Express SDK dependency graph

What’s Happening to express-jwt, express-jwt-authz, and jwks-rsa?

express-jwt, express-jwt-authz and jwks-rsa are well used and loved by many Auth0 customers and remain fully supported. There’s no need to rush to update your existing apps. We will keep fixing bugs and patching them. We plan to stop adding new features to these SDKs, though, and the bar for the bugs we fix will be tuned accordingly.

If you are about to start a new Express API project, we recommend using express-oauth2-jwt-bearer, as it will be our target for all innovation for authorization on the Node.js platform for the foreseeable future.

Try out the most powerful authentication platform for free.Get started →

What’s Next

oauth2-bearer and access-token-jwt are as yet unpublished and currently just share space in the node-oauth2-jwt-bearer monorepo. However, you can see how they could easily be used standalone or to create simple wrappers for other Node.js server frameworks like Koa.js, Nest.js, Hapi.js. You can also use them in a range of serverless platforms, which we’ll be reviewing as part of our roadmap going forward.

If you have feedback or notice any issues hit us up via the issues list or the Auth0 community.

Happy coding!

  • Twitter icon
  • LinkedIn icon
  • Faceboook icon