{"id":16812,"library":"express-basic-auth","title":"Express Basic Auth Middleware","description":"express-basic-auth is a lightweight, plug-and-play middleware designed for adding HTTP Basic Authentication to Express applications. Its current stable version is 1.2.1, with the latest release in October 2021. The package has seen sporadic updates, with v1.0.0 (production ready) in 2017 and v1.1.0 (TypeScript support) in 2020. It offers flexibility through static user configurations or custom synchronous/asynchronous authorizer functions. A key differentiator is the inclusion of a `safeCompare` utility, which aids in mitigating timing attacks for secure credential comparison. The middleware also allows customization of unauthorized responses, including JSON, and exposes parsed credentials on `req.auth`.","status":"maintenance","version":"1.2.1","language":"javascript","source_language":"en","source_url":"https://github.com/LionC/express-basic-auth","tags":["javascript","express","middleware","basic","auth","authentication","http","typescript"],"install":[{"cmd":"npm install express-basic-auth","lang":"bash","label":"npm"},{"cmd":"yarn add express-basic-auth","lang":"bash","label":"yarn"},{"cmd":"pnpm add express-basic-auth","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Runtime dependency for Express.js applications, as this package provides middleware specifically designed for Express. While not explicitly listed as a peer dependency in its package.json, it is fundamentally required for the middleware to function within an Express application.","package":"express","optional":false}],"imports":[{"note":"The `express-basic-auth` package exports its middleware function directly as a default export. For CommonJS environments, use `const basicAuth = require('express-basic-auth');`","wrong":"import { basicAuth } from 'express-basic-auth';","symbol":"basicAuth","correct":"import basicAuth from 'express-basic-auth';"},{"note":"The `safeCompare` utility function, crucial for preventing timing attacks, is exposed as a property on the default `basicAuth` middleware function, not as a separate named export.","wrong":"import { safeCompare } from 'express-basic-auth';","symbol":"safeCompare","correct":"import basicAuth from 'express-basic-auth';\n// then use basicAuth.safeCompare"},{"note":"`IOptions` is a TypeScript interface used to define the configuration object passed to the `basicAuth` middleware. It should be imported as a type for proper type checking without affecting runtime code.","wrong":"import { IOptions } from 'express-basic-auth';","symbol":"IOptions","correct":"import type { IOptions } from 'express-basic-auth';"}],"quickstart":{"code":"import express from 'express';\nimport basicAuth from 'express-basic-auth';\nimport type { IOptions } from 'express-basic-auth'; // Import the type for better DX\n\nconst app = express();\nconst port = 3000;\n\n// Example 1: Static users\napp.use('/admin-static', basicAuth({\n    users: { 'admin': 'supersecret', 'editor': 'editpass' },\n    challenge: true, // Always challenge if credentials are not provided or incorrect\n    realm: 'Static Admin Area' // Custom realm\n}));\n\n// Example 2: Custom asynchronous authorizer\nconst myAsyncAuthorizer: IOptions['authorizer'] = (username, password, cb) => {\n    // In a real app, you'd fetch from a DB, check hashed passwords, etc.\n    // Simulate async operation\n    setTimeout(() => {\n        const userMatches = basicAuth.safeCompare(username, 'customuser');\n        const passwordMatches = basicAuth.safeCompare(password, 'custompassword');\n        const authorized = userMatches && passwordMatches; // Use logical for final decision, bitwise for comparisons\n\n        if (authorized) {\n            cb(null, true); // No error, authorized\n        } else {\n            cb(null, false); // No error, not authorized\n        }\n    }, 100);\n};\n\napp.use('/admin-custom', basicAuth({\n    authorizer: myAsyncAuthorizer,\n    authorizeAsync: true, // Crucial for async authorizers\n    challenge: true,\n    realm: 'Custom Auth Area',\n    unauthorizedResponse: (req) => {\n        return req.auth ?\n            ('Credentials ' + req.auth.user + ':' + req.auth.password + ' rejected.') :\n            'No credentials provided';\n    }\n}));\n\n// Route for static users\napp.get('/admin-static', (req, res) => {\n    res.send(`Hello, ${req.auth?.user}! Welcome to the static admin area.`);\n});\n\n// Route for custom authorizer\napp.get('/admin-custom', (req, res) => {\n    res.send(`Hello, ${req.auth?.user}! Welcome to the custom authorized area.`);\n});\n\n// Public route\napp.get('/', (req, res) => {\n    res.send('This is a public page.');\n});\n\napp.listen(port, () => {\n    console.log(`Server running at http://localhost:${port}`);\n    console.log('Try accessing:');\n    console.log(` - http://localhost:${port}/admin-static (user: admin, pass: supersecret)`);\n    console.log(` - http://localhost:${port}/admin-custom (user: customuser, pass: custompassword)`);\n    console.log(` - http://localhost:${port}/`);\n});\n","lang":"typescript","description":"This quickstart demonstrates how to set up `express-basic-auth` middleware in an Express application using both static user definitions and a custom asynchronous authorizer function, showcasing secure credential comparison with `safeCompare` and custom unauthorized responses."},"warnings":[{"fix":"Ensure you are using `express-basic-auth` version 1.1.1 or higher for correct TypeScript support.","message":"TypeScript declarations in version 1.1.0 contain a known issue that can lead to compilation errors or incorrect type inference.","severity":"breaking","affected_versions":">=1.1.0 <1.1.1"},{"fix":"Always use `basicAuth.safeCompare(userInput, secret)` for comparing user-provided credentials with secrets, and prefer bitwise operators (`&`, `|`) instead of logical ones (`&&`, `||`) in custom authorizers where timing is critical.","message":"Custom authorizer functions, if not implemented carefully, can introduce timing vulnerabilities, potentially exposing secret credentials through variations in response times.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"For ESM, use `import basicAuth from 'express-basic-auth'`. For CommonJS, use `const basicAuth = require('express-basic-auth')`. Avoid named imports for the main middleware function.","message":"The package's primary export is the middleware function itself, which can lead to incorrect import statements, especially when mixing CommonJS and ESM modules.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"For ESM, change `import { basicAuth } from 'express-basic-auth'` to `import basicAuth from 'express-basic-auth'`. For CommonJS, ensure `const basicAuth = require('express-basic-auth')` is used.","cause":"Attempting to destructure the default export of `express-basic-auth` as a named export in an ESM context, or incorrect `require` syntax in CommonJS.","error":"TypeError: (0 , express_basic_auth_1.default) is not a function"},{"fix":"Upgrade `express-basic-auth` to version 1.1.1 or newer to resolve the TypeScript declaration issues. Run `npm install express-basic-auth@latest`.","cause":"This error typically occurs when using `express-basic-auth` v1.1.0 with TypeScript, as that version contained faulty type declarations.","error":"TS2345: Argument of type '{ users: { admin: string; }; }' is not assignable to parameter of type 'IOptions'."},{"fix":"Carefully review your `authorizer` function to ensure it returns `true` or `false` correctly, utilizing `basicAuth.safeCompare` for security. Ensure the `challenge` option is `true` if you expect the browser to prompt for credentials, and consider setting a `realm` for a clearer user experience (e.g., `{ challenge: true, realm: 'Restricted Area' }`).","cause":"This can happen due to incorrect comparison logic in a custom `authorizer` function, or if the `challenge` option is set to `false` (which is not the default, but possible to override) without providing an `unauthorizedResponse`.","error":"Basic authentication fails silently, or unauthorized requests are not challenged."}],"ecosystem":"npm","meta_description":null}