Passport HTTP Bearer Strategy
The `passport-http-bearer` module provides an authentication strategy for Passport.js, specifically designed to handle HTTP Bearer tokens as defined by RFC 6750. This module allows Node.js applications, particularly those using Connect-style middleware like Express, to easily integrate token-based authentication for API endpoints. Bearer tokens are a common mechanism for securing REST APIs and are frequently issued in conjunction with OAuth 2.0. The current stable version is 1.0.1, last published in 2013, indicating a mature and stable codebase with a very low release cadence, focusing on reliability rather than frequent feature additions. It differentiates itself by providing a robust, battle-tested solution for a core authentication pattern within the Passport.js framework, leveraging its pluggable middleware architecture. TypeScript definitions are available via `@types/passport-http-bearer` for enhanced developer experience.
Common errors
-
TypeError: HTTPBearerStrategy requires a verify callback
cause The `BearerStrategy` was initialized without a callback function to verify the token, or the callback was not a function.fixEnsure the `BearerStrategy` constructor receives a valid function as its second argument (or first, if no options object is provided). Example: `new BearerStrategy(function(token, done) { /* ... */ })`. -
HTTP 401 Unauthorized / { "message": "Unauthorized" } (or similar)cause The bearer token provided in the request was invalid, missing, or the `verify` callback returned `done(null, false)` indicating authentication failure. Passport's default behavior for failing authentication is to send a 401.fixVerify the client is sending the token correctly in the `Authorization: Bearer <token>` header or as `access_token` in query/body. Debug the `verify` callback to ensure it correctly finds and validates the token against your user/token store. Custom error messages can be returned via `done(null, false, { message: 'Custom message' })`. -
Error: bearer.authenticate() requires a callback function (or similar Passport internal error)
cause This error typically indicates that `passport.authenticate('bearer')` was called without a valid callback or that the middleware chain was incorrectly configured, preventing Passport from handling the request properly.fixEnsure `passport.authenticate('bearer', { session: false })` is correctly placed as middleware in your route. If you are handling authentication outcome manually, ensure `passport.authenticate('bearer', function(err, user, info) { /* ... */ })(req, res, next)` uses a valid callback and immediately invokes it with `(req, res, next)`.
Warnings
- gotcha Bearer tokens are credentials that grant access to resources to anyone who possesses them. They must be protected from disclosure both in storage and during transport (e.g., always use HTTPS). Treat them with the same security considerations as passwords.
- gotcha When using `passport.authenticate('bearer')` for API routes, it is generally recommended to set `session: false`. Bearer token authentication is typically stateless, and not using sessions reduces overhead and potential attack vectors related to session management.
- gotcha The `BearerStrategy`'s `verify` callback can optionally receive the `req` object as its first argument by setting `passReqToCallback: true` in the strategy options. Forgetting this option or mismatching the callback signature can lead to unexpected behavior or `undefined` values.
- gotcha In TypeScript, incorrect type definitions for the `verify` callback can lead to implicit `any` errors or type mismatches, especially when `passReqToCallback` is involved.
Install
-
npm install passport-http-bearer -
yarn add passport-http-bearer -
pnpm add passport-http-bearer
Imports
- Strategy
const BearerStrategy = require('passport-http-bearer').Strategy;import { Strategy as BearerStrategy } from 'passport-http-bearer'; - BearerStrategy (CommonJS)
const BearerStrategy = require('passport-http-bearer').Strategy; - BearerStrategy (Type Import)
import { Strategy as BearerStrategy } from 'passport-http-bearer'; import { VerifyFunction, VerifyFunctionWithRequest } from 'passport-http-bearer';
Quickstart
import express from 'express';
import passport from 'passport';
import { Strategy as BearerStrategy } from 'passport-http-bearer';
const app = express();
const PORT = process.env.PORT || 3000;
// Dummy User/Token database for example purposes
const users = [
{ id: '1', username: 'testuser', token: 'a1b2c3d4e5f6' },
];
// Configure the Bearer strategy
passport.use(new BearerStrategy(
async (token, done) => {
console.log(`Attempting to verify token: ${token}`);
try {
const user = users.find(u => u.token === token);
if (!user) {
console.log('Invalid token provided.');
return done(null, false, { message: 'Invalid token' });
}
console.log(`Token verified for user: ${user.username}`);
return done(null, user, { scope: 'all' });
} catch (err) {
console.error('Error during token verification:', err);
return done(err);
}
}
));
// Initialize Passport
app.use(passport.initialize());
// Protected route using bearer authentication
app.get('/api/protected',
passport.authenticate('bearer', { session: false }),
(req, res) => {
// If authentication successful, req.user will be populated
const user = req.user as typeof users[0] | undefined;
if (user) {
res.json({ message: `Hello, ${user.username}! You have access to protected data.` });
} else {
res.status(401).json({ message: 'Authentication required.' });
}
}
);
// Start the server
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log('Test with: curl -H "Authorization: Bearer a1b2c3d4e5f6" http://localhost:3000/api/protected');
console.log('Test with invalid token: curl -H "Authorization: Bearer wrongtoken" http://localhost:3000/api/protected');
});