HTTP Basic Authentication for Node.js
The `basic-authentication` package provides a flexible solution for implementing HTTP Basic Authentication in Node.js applications, particularly designed for integration with Express.js as middleware. Currently stable at version 1.10.0, its release cadence has focused on ensuring compatibility with newer Node.js versions, with major changes often addressing Node.js engine support or dependency updates. Key differentiators include its versatile API, allowing usage as a global Express middleware, a route-specific callback, or a standalone function for custom authentication logic. It supports authentication against a specified username and password, or by parsing an `htpasswd` file with various hashing algorithms. Unlike simpler basic auth packages, it offers explicit control over response handling (`ending` flag) and error suppression (`suppress` flag), making it adaptable to diverse application architectures. It currently maintains compatibility with Node.js versions 4 and above.
Common errors
-
TypeError: basicAuth is not a function
cause The `require('basic-authentication')` statement was not immediately invoked with parentheses.fixChange `const basicAuth = require('basic-authentication');` to `const basicAuth = require('basic-authentication')();` (or pass options: `require('basic-authentication')(options)`). -
HTTP 401 Unauthorized
cause Invalid username or password provided, or no credentials were sent. This could also be due to an incorrect `htpasswd` file path or hash configuration.fixCheck the username and password in the client request. Verify the `user`, `password`, `file`, and `hash` options in your `basic-authentication` configuration. Ensure the `realm` is correctly set if using custom values. -
TypeError: Cannot read properties of undefined (reading 'user') // when using functions or legacy mode
cause Attempting to access `user` or `password` properties on the return value of `basic-authentication` when not in `legacy` mode, or when authentication failed in `legacy` mode (which returns an empty object).fixIf using `functions: true`, the return value is a Base64 string, not an object. If using `legacy: true`, ensure you check for an empty object `{}` before accessing properties, indicating authentication failure.
Warnings
- breaking Support for Node.js versions below 4 was removed in `basic-authentication@1.8.0`. Applications targeting older Node.js environments must use an earlier package version.
- gotcha The module's behavior and return type are drastically altered by the `functions` and `legacy` options. Without these, it returns an Express middleware. With `functions: true`, it returns a function that takes `req` and returns a Base64 string (username). With `legacy: true`, it returns an object `{user, password}`.
- breaking The license changed from GPL3 to Apache2 in version 1.9.0. This is a significant change in terms of legal implications for projects depending on this package.
- gotcha When using the `file` option for htpasswd authentication, ensure the `hash` option correctly specifies the hashing algorithm (e.g., 'md5') used in your `.htpasswd` file. Incorrect hash types will lead to failed authentication.
Install
-
npm install basic-authentication -
yarn add basic-authentication -
pnpm add basic-authentication
Imports
- authenticationMiddleware
import authenticationMiddleware from 'basic-authentication';
const authenticationMiddleware = require('basic-authentication')(); - configuredAuthenticationFunction
const authFunction = require('basic-authentication'); // Then later trying authFunction({ functions: true });const authFunction = require('basic-authentication')({ functions: true }); - legacyAuthenticationObject
const authObject = require('basic-authentication')({ functions: true }); // Expecting an object, getting a stringconst authObject = require('basic-authentication')({ legacy: true });
Quickstart
const express = require('express');
const basicAuth = require('basic-authentication');
const app = express();
// Configure basic authentication with a custom user and password
const authMiddleware = basicAuth({
user: process.env.AUTH_USER || 'myuser',
password: process.env.AUTH_PASSWORD || 'mypassword',
realm: 'Restricted Area'
});
// Apply the authentication middleware to a specific route
app.get('/protected', authMiddleware, (req, res) => {
res.send('Welcome, authenticated user!');
});
// Or use it in a more functional way for advanced logic
const authChecker = basicAuth({ functions: true });
app.get('/admin', (req, res) => {
const user = authChecker(req);
if (user === (process.env.AUTH_USER || 'myuser')) {
res.send(`Hello, admin ${user}!`);
} else {
res.status(401).send('Unauthorized: Invalid admin user.');
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log('Try accessing http://localhost:3000/protected with user:myuser and pass:mypassword');
});