Express Smart Authentication Middleware
This package, `smart-auth-middleware`, is an Express.js middleware designed for authenticating incoming requests by validating JSON Web Tokens (JWTs) against an external Identity Service (IDS). It integrates with `jwks-rsa` for fetching JSON Web Key Sets and `express-jwt` for the core JWT verification process. Currently at version 0.21.0, it is in active development, implying that breaking changes might occur more frequently between minor versions as it approaches a stable 1.0 release. The middleware provides a lifecycle with `authPreCheck` for initial validation, `jwtVerify` for token verification and setting user information on `req.user`, and `authPostCheck` to ensure verification success. Its key differentiators include built-in support for JWKS endpoints and configurable options for issuer, audience, and ignored paths, streamlining JWT-based authentication in Express applications.
Common errors
-
Error: IDENTITY_SERVICE_URL is mandatory configuration.
cause The `IDENTITY_SERVICE_URL` option was not provided or was an empty string when initializing the middleware.fixEnsure `IDENTITY_SERVICE_URL` is set to a valid URL in the options object passed to `authentication()`. -
UnauthorizedError: No authorization token was found
cause The `Authorization` header was missing or empty in the incoming HTTP request.fixThe client must provide an `Authorization` header with a valid JWT, prefixed by `Bearer` (e.g., `Authorization: Bearer YOUR_JWT_TOKEN`). -
UnauthorizedError: Invalid token
cause The provided JWT was malformed, expired, had an incorrect signature, or did not pass other validation checks (e.g., issuer, audience).fixVerify that the JWT is correctly formed, has not expired, is signed by a trusted issuer, and matches the expected audience configured in the middleware options.
Warnings
- breaking As a package in the `0.x.x` version series, `smart-auth-middleware` may introduce breaking changes in minor versions (e.g., from 0.20.x to 0.21.x) without adhering to semantic versioning for major changes. Always review changelogs when updating.
- gotcha The `IDENTITY_SERVICE_URL` option is mandatory. If it's not provided or is misconfigured, the middleware's `authPreCheck` method will throw an error, preventing the application from starting or processing requests.
- gotcha Error handling for `UnauthorizedError` from the underlying `express-jwt` library must be explicitly implemented as an Express error handling middleware (`app.use((err, req, res, next) => { ... })`). Failing to do so will result in unhandled exceptions.
- gotcha The middleware expects a JWT in the `Authorization` header with a `Bearer` prefix (e.g., `Authorization: Bearer <token>`). Using incorrect header names or token formats will result in authentication failure.
Install
-
npm install smart-auth-middleware -
yarn add smart-auth-middleware -
pnpm add smart-auth-middleware
Imports
- authentication
import { authentication } from 'smart-auth-middleware';import authentication from 'smart-auth-middleware';
- authentication
const { authentication } = require('smart-auth-middleware');const authentication = require('smart-auth-middleware'); - Auth Options
import { options } from 'smart-auth-middleware';// No direct import for options object, it's passed directly to the middleware function
Quickstart
import express from 'express';
import authentication from 'smart-auth-middleware';
const app = express();
const router = express.Router();
// Ensure environment variables are set or provide fallbacks
const options = {
IDENTITY_SERVICE_URL: process.env.IDENTITY_SERVICE_URL ?? 'http://localhost:3000/identity',
ISSUER: process.env.JWT_ISSUER ?? 'your-issuer-url',
AUDIENCE: process.env.JWT_AUDIENCE ?? 'your-audience',
ignorePaths: [ '/healthcheck', '/ping' ]
};
// Apply the authentication middleware to all routes under '/'
// All routes after this middleware will require a valid JWT, except ignoredPaths
app.use('/', authentication(options), router);
router.get('/secure-data', (req, res) => {
// req.user will be populated by the middleware if token is valid
if (req.user) {
res.status(200).json({ message: 'Access granted to secure data', user: req.user });
} else {
res.status(401).json({ message: 'Unauthorized: req.user not found' });
}
});
router.get('/healthcheck', (req, res) => {
res.status(200).send('Service is healthy');
});
// Basic error handling middleware for express-jwt errors
app.use((err, req, res, next) => {
if (err.name === 'UnauthorizedError') {
res.status(401).json({ message: 'Invalid token: ' + err.message });
} else {
next(err);
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
console.log('Test with: curl -H "Authorization: Bearer <YOUR_JWT>" http://localhost:3000/secure-data');
console.log('Or: curl http://localhost:3000/healthcheck');
});