Express X-Hub Signature Middleware
raw JSON →The `express-x-hub` package provides an Express.js middleware for validating X-Hub-Signature requests. It was designed to ensure the integrity of incoming webhooks, particularly useful for platforms like Facebook real-time updates and GitHub webhooks, by verifying the request body against a secret using the `X-Hub-Signature` header. The current and only stable version is 1.0.4, last published in October 2015. This package is no longer actively maintained or updated, making it effectively abandoned. Its primary differentiation was its specific focus on adding validation methods directly to the `req` object (`req.isXHub`, `req.isXHubValid()`) within the Express middleware flow, requiring placement *before* any body parsing middleware. It does not provide official TypeScript types.
Common errors
error Property 'isXHubValid' does not exist on type 'Request<{}, any, any, ParsedQs, Record<string, any>>'. ↓
src/types/express-x-hub.d.ts) to your project to augment the express.Request interface. Example content: declare namespace Express { interface Request { isXHub?: boolean; isXHubValid(): boolean; } }. Ensure this file is included in your tsconfig.json. error Error: Invalid X-Hub Signature ↓
secret configured in the middleware matches the secret used by the webhook sender. 2. Ensure the X-Hub-Signature header is present and correctly formatted in the incoming request. 3. Crucially, confirm that express-x-hub is mounted *before* any body-parser or other middleware that consumes the raw request body. Warnings
gotcha The `express-x-hub` middleware *must* be mounted before any `body-parser` middleware. X-Hub signatures are calculated over the raw request body. If `body-parser` processes the request first, the raw body will be consumed and unavailable for `express-x-hub`, leading to validation failures. ↓
deprecated The `express-x-hub` package (v1.0.4) was last published in October 2015 and appears to be unmaintained and effectively abandoned. While it still functions, consider migrating to a more actively maintained X-Hub-Signature validation library, such as `x-hub-signature` (which offers a separate middleware package `x-hub-signature-middleware` for Express) for better security and ongoing support. ↓
gotcha This package does not ship with official TypeScript declaration files. When used in a TypeScript project, the `req.isXHub` and `req.isXHubValid()` properties will not be recognized by the compiler, leading to type errors unless custom declaration merging is used. ↓
Install
npm install express-x-hub yarn add express-x-hub pnpm add express-x-hub Imports
- xhub wrong
import xhub from 'express-x-hub';correctconst xhub = require('express-x-hub'); - req.isXHub
if (!req.isXHub) { /* handle non-xhub request */ } - req.isXHubValid
if (!req.isXHubValid()) { /* handle invalid signature */ }
Quickstart
import express from 'express';
import bodyParser from 'body-parser';
const xhub = require('express-x-hub');
const app = express();
const PORT = process.env.PORT || 3000;
const XHUB_SECRET = process.env.XHUB_SECRET || 'your-super-secret-key';
if (!XHUB_SECRET || XHUB_SECRET === 'your-super-secret-key') {
console.warn('WARNING: XHUB_SECRET is not set or using default. Please set `process.env.XHUB_SECRET` for production.');
}
// IMPORTANT: express-x-hub middleware MUST be placed before body-parser
app.use(xhub({ algorithm: 'sha1', secret: XHUB_SECRET }));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/webhook', (req, res) => {
console.log('Received webhook request.');
// Check if it's an X-Hub request at all
if (!req.isXHub) {
console.log('Request is not X-Hub.');
return res.status(400).send('No X-Hub Signature Found');
}
// Validate the X-Hub signature
if (!req.isXHubValid()) {
console.warn('Invalid X-Hub Signature!');
return res.status(401).send('Invalid X-Hub Signature');
}
// If valid, process the request
console.log('X-Hub Signature is valid. Processing request body:', req.body);
res.status(200).json({ status: 'X-Hub Is Valid', data: req.body });
});
app.get('/', (req, res) => {
res.send('X-Hub test server running. Send POST requests to /webhook');
});
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
console.log(`Test with: curl -X POST -H "X-Hub-Signature: sha1=your_test_signature" -H "Content-Type: application/json" -d '{"key":"value"}' http://localhost:${PORT}/webhook`);
});