Passport HTTP Header Authentication Strategy

raw JSON →
1.1.0 verified Thu Apr 23 auth: no javascript maintenance

The `passport-http-header-strategy` package provides a flexible HTTP header-based authentication strategy for the Passport.js framework. It enables developers to authenticate requests by extracting a token from a custom HTTP header (e.g., `X-API-Key`), or optionally from a request body or query parameter, rather than being limited to the standard `Authorization: Bearer` scheme. Currently at version 1.1.0, the package has not seen significant updates in several years, suggesting a stable but largely unmaintained status. It integrates seamlessly into existing Passport-based applications, allowing for stateless (session-less) authentication, which is common for API-driven services. Its key differentiator is the configurability of the header name and parameter name, offering more customization than some other token-based strategies.

error Unknown authentication strategy "header"
cause The Passport strategy has not been correctly registered or the name used in `passport.authenticate()` does not match the name provided to `passport.use()`.
fix
Ensure you call passport.use('your-strategy-name', new Strategy(...)) and then use passport.authenticate('your-strategy-name', ...) with the exact same string name.
error Strategy must be given a verify callback
cause The second argument to the `Strategy` constructor (the function responsible for verifying the token) is missing or not a function.
fix
Provide a valid function as the second argument to new Strategy(options, verifyCallback). This function is where you implement your token validation logic.
error TypeError: Cannot read properties of undefined (reading 'authenticate')
cause Passport middleware (`passport.initialize()`) is not configured or mounted correctly in your Express application, or `passport` is not properly imported.
fix
Ensure you have app.use(passport.initialize()); (and optionally app.use(passport.session()); if using sessions, though not recommended for this strategy) before any routes that use passport.authenticate().
error 401 Unauthorized (when token is present and valid)
cause Your `verify` callback is incorrectly calling `done(null, false)` or `done(error)` even when the token is valid, or your token extraction logic is flawed.
fix
Carefully debug your verify callback. Ensure done(null, user) is called with a valid user object upon successful authentication. Check that the header or param options correctly match where your token is sent.
gotcha It is critical to set `session: false` when using token-based authentication strategies like `passport-http-header-strategy`. This prevents Passport from attempting to create or use a session, which is unnecessary and potentially problematic for stateless API authentication.
fix Always include `{ session: false }` in the `passport.authenticate()` options for token strategies.
gotcha The `passReqToCallback` option changes the signature of the `verify` callback. If set to `true`, the first argument to your callback will be the `req` object. Incorrectly matching the callback signature will lead to runtime errors or unexpected behavior.
fix Ensure your `verify` callback signature matches `(req, token, done)` if `passReqToCallback: true`, or `(token, done)` if `passReqToCallback: false`.
breaking This package has not been updated in several years. While it may still function with recent Passport.js versions, there's a risk of incompatibility with newer Node.js releases, potential security vulnerabilities (though none specifically reported for this package), or lack of support for modern language features.
fix Thoroughly test with your target Node.js and Passport.js versions. Consider migrating to a more actively maintained strategy or implementing a custom strategy if advanced features or recent updates are critical.
gotcha The example `User.findOne({ token: token })` from the README is insecure for production use. Raw tokens should never be stored directly in a database. Tokens should be hashed or, if JWTs, signed and verified without storing the full token.
fix Implement proper token security measures: use strong cryptographic hashing (e.g., bcrypt) for API keys/static tokens, or verify JWTs using their signature and claims rather than simple database lookups.
npm install passport-http-header-strategy
yarn add passport-http-header-strategy
pnpm add passport-http-header-strategy

This quickstart demonstrates setting up an Express application with Passport.js and the `passport-http-header-strategy` to protect a route using a custom `X-APP-TOKEN` header. It includes a mock user database and instructions for testing via cURL.

import express from 'express';
import passport from 'passport';
import { Strategy } from 'passport-http-header-strategy';

const app = express();
app.use(express.json()); // For parsing req.body if 'param' option is used

// Mock user database for demonstration
const users = [
  { id: 1, username: 'testuser', token: 'mysecrettoken123' },
  { id: 2, username: 'admin', token: 'adminsecuretoken' }
];

// Configure the HTTP Header Strategy
passport.use('header-token', new Strategy({
    header: 'X-APP-TOKEN',          // Name of the header to check for the token
    param: 'app_token',            // Optional: Name of param in req.body/req.query if header isn't found
    passReqToCallback: true        // Pass the request object to the verify callback
  },
  function(req, token, done) {
    console.log(`Attempting authentication with token: ${token} from header: ${req.headers['x-app-token']}`);

    const user = users.find(u => u.token === token);

    if (!user) {
      return done(null, false, { message: 'Invalid token provided.' });
    }
    // In a real application, perform secure token validation (e.g., database lookup, JWT verification)
    return done(null, user, { scope: 'all' });
  }
));

// Protected route using the 'header-token' strategy
app.get('/protected', 
  passport.authenticate('header-token', { session: false }),
  function(req, res) {
    res.json({ 
      message: `Hello, ${req.user.username}! This is a protected resource.`, 
      user: req.user 
    });
  }
);

// Unprotected root route
app.get('/', (req, res) => {
    res.send('Welcome. Try GET /protected with an X-APP-TOKEN header.');
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
  console.log('Test with cURL:');
  console.log(`curl -H "X-APP-TOKEN: mysecrettoken123" http://localhost:${PORT}/protected`);
  console.log(`curl http://localhost:${PORT}/protected`); // Should result in 401 Unauthorized
});