Node.js Example
Node.js requires regex replacements to add spaces after colons and commas to match Python's formatting.
const crypto = require('crypto');
// Step 1: Extract signature from header
const receivedSignature = req.headers['ap-signature'];
// Step 2: Get webhook body
const body = req.body;
// Step 3: Build payload for signing
const payload = {
...body, // All fields from webhook body
url: 'https://your-registered-webhook-url.com'
};
// Step 4: Serialize with Python-compatible formatting
// NOTE: This regex approach has known limitations with complex nested structures.
// Test thoroughly with your specific webhook payloads.
const payloadStr = JSON.stringify(payload)
.replace(/"((?:[^"\\]|\\.)*)"\s*:/g, '"$1": ') // space after colons
.replace(/,(?=\s*["{[0-9tfn])/g, ', '); // space after commas
// Step 5: Compute expected signature
const hmac = crypto.createHmac('sha256', signingKey);
hmac.update(payloadStr);
const expectedSignature = hmac.digest('hex');
// Step 6: Validate (use constant-time comparison)
const isValid = crypto.timingSafeEqual(
Buffer.from(receivedSignature),
Buffer.from(expectedSignature)
);
if (isValid) {
// Webhook is authentic - safe to process
processWebhook(body);
} else {
// Invalid signature - reject
res.status(401).send('Unauthorized');
}
Node.js Limitation:The regex replacement approach has known limitations with complex nested structures (arrays of objects, mixed-type arrays). We recommend testing your implementation against real sandbox webhooks before deploying to production.
Updated about 14 hours ago
