---
title: "Introducing the OAuth 2.0 Express SDK for Protecting APIs with JWT Bearer Tokens"
description: "Learn how the OAuth 2.0 Express SDK released by Auth0 makes protecting your Express API easier."
authors:
  - name: "Adam McGrath"
    url: "https://auth0.com/blog/authors/adam-mcgrath/"
date: "Mar 24, 2022"
category: "Developers,Product,SDK"
tags: ["nodejs", "node", "express", "oauth2", "jwt", "api"]
url: "https://auth0.com/blog/introducing-oauth2-express-sdk-protecting-api-with-jwt/"
---

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

Auth0 has released [express-oauth2-jwt-bearer](https://github.com/auth0/node-oauth2-jwt-bearer/tree/main/packages/express-oauth2-jwt-bearer), a new [Express](https://expressjs.com/) 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](https://github.com/auth0/express-jwt), [express-jwt-authz](https://github.com/auth0/express-jwt-authz), and [jwks-rsa](https://github.com/auth0/node-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](https://auth0.com/docs/quickstart/backend/nodejs) before and after implementing the new SDK, as shown in the following screenshot:

![SDK code lines comparison](https://images.ctfassets.net/23aumh6u8s0i/3Mkzs9yeeOboyJkwJIR9Pb/2518cadc35f2e378edbb5cb925f69026/express-sdk-comparison.jpg)

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](https://github.com/auth0/express-oauth2-bearer), was released experimentally to support our excellent [Identity Labs](https://auth0.com/docs/identity-labs/identity-lab-2-calling-api) series ([express-oauth2-bearer](https://github.com/auth0/express-oauth2-bearer) will now be deprecated in favor of [express-oauth2-jwt-bearer](https://github.com/auth0/node-oauth2-jwt-bearer/tree/main/packages/express-oauth2-jwt-bearer)).

## The Role of Standards

[express-oauth2-jwt-bearer](https://github.com/auth0/node-oauth2-jwt-bearer/tree/main/packages/express-oauth2-jwt-bearer) protects Express APIs using a combination of the well-established [OAuth2 Bearer Token Usage spec](https://datatracker.ietf.org/doc/html/rfc6750) and the new specification of [JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens](https://datatracker.ietf.org/doc/html/rfc9068).

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](https://datatracker.ietf.org/doc/html/rfc9068), they are able to leverage new standards to consume Access Token JWTs in an interoperable manner. [express-oauth2-jwt-bearer](https://github.com/auth0/node-oauth2-jwt-bearer/tree/main/packages/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](https://github.com/auth0/node-oauth2-jwt-bearer/tree/main/packages/express-oauth2-jwt-bearer) uses a similar mechanism to [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) 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:

```bash
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:

```bash
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](https://manage.auth0.com/). 

Then add the [express-oauth2-jwt-bearer](https://github.com/auth0/node-oauth2-jwt-bearer/tree/main/packages/express-oauth2-jwt-bearer) middleware to your API like so:

```javascript
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:

```bash
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](https://manage.auth0.com/#/apis), as shown in the following picture:

![Copy access token from Auth0 Dashboard](https://images.ctfassets.net/23aumh6u8s0i/785NRBn9KBkiML9UF3NGO5/bcd2954c29af6637f783426e7b89ed7c/copy-access-token.png)

Check out [express-openid-connect](https://github.com/auth0/express-openid-connect) to see an example of how to [programmatically obtain an Access Token to call external APIs](https://github.com/auth0/express-openid-connect/blob/master/EXAMPLES.md#4-obtaining-access-tokens-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:

```javascript
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](https://auth0.github.io/node-oauth2-jwt-bearer#claimcheck), [claimEquals](https://auth0.github.io/node-oauth2-jwt-bearer#claimequals), and [claimIncludes](https://auth0.github.io/node-oauth2-jwt-bearer#claimincludes) (see [the docs for the full API](https://github.com/auth0/node-oauth2-jwt-bearer/tree/main/packages/express-oauth2-jwt-bearer#api-documentation)).

## Under the Hood

[express-oauth2-jwt-bearer](https://github.com/auth0/node-oauth2-jwt-bearer/tree/main/packages/express-oauth2-jwt-bearer) is a small [Express](https://expressjs.com/) wrapper around two framework agnostic packages:

- [oauth2-bearer](https://github.com/auth0/node-oauth2-jwt-bearer/blob/main/packages/oauth2-bearer): it gets Bearer tokens from a request and issues errors per the [Bearer Token Usage spec](https://tools.ietf.org/html/rfc6750).
- [access-token-jwt](https://github.com/auth0/node-oauth2-jwt-bearer/blob/main/packages/access-token-jwt): it verifies and decodes Access Token JWTs following the [JWT Profile for OAuth 2.0 Access Tokens spec](https://datatracker.ietf.org/doc/html/rfc9068) using the [jose](https://github.com/panva/jose) library.

The following diagram shows the dependencies among these packages:

![OAuth2 Express SDK dependency graph](https://images.ctfassets.net/23aumh6u8s0i/78D0oQvCSHj5SUTANEFihw/31924abc24a7841cbb73db1afd297f83/oauth2-express-libraries-dependency.png)

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

[express-jwt](https://github.com/auth0/express-jwt), [express-jwt-authz](https://github.com/auth0/express-jwt-authz) and [jwks-rsa](https://github.com/auth0/node-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](https://github.com/auth0/node-oauth2-jwt-bearer/tree/main/packages/express-oauth2-jwt-bearer), as it will be our target for all innovation for authorization on the Node.js platform for the foreseeable future.

<include src="SignupCTA" text="Try out the most powerful authentication platform for free." linkText="Get started →" />

## What’s Next

[oauth2-bearer](https://github.com/auth0/node-oauth2-jwt-bearer/blob/main/packages/oauth2-bearer) and [access-token-jwt](https://github.com/auth0/node-oauth2-jwt-bearer/blob/main/packages/access-token-jwt) are as yet unpublished and currently just share space in the [node-oauth2-jwt-bearer](https://github.com/auth0/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](https://www.simform.com/blog/best-nodejs-frameworks/#Koa), [Nest.js](https://www.simform.com/blog/best-nodejs-frameworks/#Nest), [Hapi.js](https://www.simform.com/blog/best-nodejs-frameworks/#Hapi). 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](https://github.com/auth0/node-oauth2-jwt-bearer/issues) or the [Auth0 community](https://community.auth0.com/).

Happy coding!
