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.
npm i jose --save
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:
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();
};