Protect your API on Node(Express)

Extract the Bearer Token from the request header

An authorized request should contain an Authorization header with Bearer <access_token> as its content. Extract the Authorization Token from the request header:

// auth_middleware.ts

import { IncomingHttpHeaders } from 'http';

const extractBearerTokenFromHeaders = ({ authorization }: IncomingHttpHeaders) => {
 if (!authorization) {
   throw new Error({ code: 'auth.authorization_header_missing', status: 401 });
 }

 if (!authorization.startsWith('Bearer')) {
   throw new Error({ code: 'auth.authorization_token_type_not_supported', status: 401 });
 }

 return authorization.slice(bearerTokenIdentifier.length + 1);
};

Token validation

For demonstration, we use the jose package to validate the token's signature, expiration status, and required claims.

Install jose as your dependency

npm i jose --save

Retrieve Auth’s OIDC configurations

You will need a JWK public key set and the token issuer to verify the signature and source of the received JWS token. All the public Auth Authorization Configurations can be found at https://your-auth-domain/.well-known/openid-configuration.

e.g. Call https://nightly-accounts-api.complyment.com/.well-known/openid-configuration. And locate the following two fields in the response body:

{
 "jwks_uri": "https://nightly-accounts-api.complyment.com/.well-known/jwks.json",
 "issuer": "https://nightly-accounts-api.complyment.com"
}

Add auth middleware

Jose's jwtVerify method may help you to verify the token's JWS format, token signature, issuer, audience and the expiration status. An exception will be thrown if validation fails.

// auth-middleware.ts
import { createRemoteJWKSet, jwtVerify } from 'jose';
//...
export const verifyAuthFromRequest = async (req, res, next) => {
 // Extract the token
 const token = extractBearerTokenFromHeaders(req.headers);
 const { payload } = await jwtVerify(
   token, // The raw Bearer Token extracted from the request header
   createRemoteJWKSet('https://<your-auth-domain>/oidc/jwks'), // generate a jwks using jwks_uri inquired from Auth server
   {
     // expected issuer of the token, should be issued by the Auth server
     issuer: 'https://<your-auth-domain>',
     // expected audience token, should be the resource indicator of the current API
     audience: '<your request listener resource indicator>',
   }
 );
 // custom payload logic
 userId = payload.sub;
 return next();
};

Apply middleware to your API

import { verifyAuthFromRequest } from '/middleware/auth-middleware.ts';

app.get('/user/:id', verifyAuthFromRequest, (req, res, next) => {
 // Custom code
});

Last updated