Basic Auth Middleware for Express.js
basicauth-middleware is an Express.js middleware designed for implementing HTTP Basic Authentication on web routes. Currently at version 3.1.1, the package is in a maintenance state, with the last major update (v3) occurring in 2021 which dropped support for Node.js versions below 10 and enhanced asynchronous credential checking. It allows for flexible authentication strategies, accepting plain username/password pairs, arrays of credentials, or custom synchronous/asynchronous callback functions, including Promise-based and async/await syntax. This middleware is suitable for protecting administrative interfaces, APIs, or internal tools where a simple, stateless authentication mechanism is sufficient. Key differentiators include its simplicity and versatility in defining authentication logic directly within the application.
Common errors
-
TypeError: basicauth is not a function
cause Attempting to use `basicauth-middleware` with an incorrect import statement (e.g., `import basicauth from 'basicauth-middleware';` in a CJS context or without proper ESM configuration) or if the `require` statement returned `undefined`.fixEnsure you are using `const basicauth = require('basicauth-middleware');` for CommonJS projects. If using ESM, you might need a transpiler or a Node.js version with full ESM-CJS interop and potentially a custom loader if the package isn't dual-bundled. -
Error: Not Authenticated
cause This is a common custom error message returned by the middleware when authentication fails. It indicates that the provided credentials (username/password) were incorrect or not provided in the `Authorization` header, based on the configured authentication logic.fixDouble-check the username and password being sent by the client. Verify the middleware's configuration (plain credentials or custom callback logic) ensures it matches expected values. Inspect the network request to confirm the `Authorization` header is correctly formatted (`Basic <base64-encoded-credentials>`). -
ERR_REQUIRE_ESM
cause This error occurs when a CommonJS `require()` call attempts to load an ES Module (ESM) that does not provide a CommonJS export, typically in a project where `type: module` is set in `package.json` or you're trying to mix module types incorrectly.fixAs `basicauth-middleware` is primarily CJS, if your project is ESM-native, you might need to use dynamic `import()`: `const basicauth = await import('basicauth-middleware')`. Alternatively, ensure your build setup correctly handles CJS interop, or use an older Node.js version if still on `type: commonjs` and encountering issues.
Warnings
- breaking Version 3.0.0 of `basicauth-middleware` dropped support for Node.js versions older than 10. Applications running on Node.js 6 or 8 (which were supported by v2) will break upon upgrading to v3.
- breaking The behavior of authentication callbacks changed significantly in v3. While older versions primarily relied on synchronous or Node-style async callbacks, v3 embraces Promises and async/await. Callback functions are now expected to return a boolean or a Promise resolving to a boolean, rather than using a `cb(err, result)` signature.
- gotcha Basic Authentication transmits credentials Base64-encoded, not encrypted. If used over HTTP, credentials can be easily intercepted and decoded. This poses a significant security risk for sensitive applications.
- gotcha When implementing custom authentication callbacks, standard string comparisons (e.g., `===`) for passwords can be vulnerable to timing attacks, where an attacker deduces parts of a password by measuring response times.
- gotcha If the `basicauth` middleware is not called with arguments (e.g., `app.use(basicauth);`), it will not function correctly and will likely throw an error or fail to protect routes, as it expects configuration arguments.
Install
-
npm install basicauth-middleware -
yarn add basicauth-middleware -
pnpm add basicauth-middleware
Imports
- basicauth
import basicauth from 'basicauth-middleware';
const basicauth = require('basicauth-middleware'); - basicauth (with named export pattern, though not explicitly supported)
import { basicauth } from 'basicauth-middleware';const basicauth = require('basicauth-middleware'); - basicauth (as an Express middleware function)
app.use(basicauth); // Missing arguments for configuration
app.use(basicauth('user', 'pass'));
Quickstart
const express = require('express');
const basicauth = require('basicauth-middleware');
const app = express();
// Simulate an asynchronous user database check
const verifyUser = async (username, password) => {
console.log(`Attempting to authenticate user: ${username}`);
return new Promise(resolve => {
setTimeout(() => {
// In a real app, you'd check a database or external service
if (username === process.env.AUTH_USERNAME && password === process.env.AUTH_PASSWORD) {
console.log(`User ${username} authenticated successfully.`);
resolve(true);
} else {
console.log(`Authentication failed for user: ${username}.`);
resolve(false);
}
}, 100);
});
};
// Protect all routes under /admin with basic authentication
app.use('/admin', basicauth(verifyUser, 'Admin Area'));
// A protected route
app.get('/admin/dashboard', (req, res) => {
res.send('Welcome to the Admin Dashboard, authenticated user!');
});
// An unprotected route
app.get('/', (req, res) => {
res.send('Public homepage.');
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log('Access http://localhost:3000/admin/dashboard (requires AUTH_USERNAME and AUTH_PASSWORD environment variables)');
});
// To run this, set environment variables:
// AUTH_USERNAME=testuser
// AUTH_PASSWORD=testpass