Passport HTTP Header Authentication Strategy
raw JSON →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.
Common errors
error Unknown authentication strategy "header" ↓
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 ↓
new Strategy(options, verifyCallback). This function is where you implement your token validation logic. error TypeError: Cannot read properties of undefined (reading 'authenticate') ↓
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) ↓
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. Warnings
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. ↓
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. ↓
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. ↓
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. ↓
Install
npm install passport-http-header-strategy yarn add passport-http-header-strategy pnpm add passport-http-header-strategy Imports
- Strategy wrong
const Strategy = require('passport-http-header-strategy');correctimport { Strategy } from 'passport-http-header-strategy'; - Passport wrong
import { Passport } from 'passport';correctimport passport from 'passport'; - VerifyCallback
type VerifyCallback = (req: Request, token: string, done: (error: any, user?: any, info?: any) => void) => void;
Quickstart
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
});