Unable to verify webhook signature on Node.JS

Hello,

I am trying to verify the webhook signature and I cannot get it working. I am following https://docs.rapyd.net/en/webhook-authentication.html guide, but the calculated signature is different from the signature sent.

import { createHmac } from 'crypto';

// the request object is an express request object
const bodyString = request.rawBody ? request.rawBody.toString('utf8') : '';
const salt = request.get('salt');
const signature = request.get('signature');
const timestamp = request.get('timestamp');
const url = request.protocol + '://' + request.get('host') + request.originalUrl;
const accessKey = process.env.RAPYD_ACCESS_KEY;
const secretKey = process.env.RAPYD_SECRET_KEY;
const data = `${url}${salt}${timestamp}${accessKey}${secretKey}${bodyString !== '{}' : bodyString : ''}`;
let hash;
let calculatedSignature;

try {
  hash = createHmac('sha256', secretKey);
  hash.update(data);

  calculatedSignature = Buffer.from(hash.digest('hex')).toString('base64');
} catch (error) {
  console.error(error);

  throw new Error('InternalServerError');
}

if (calculatedSignature !== signature) {
  throw new Error('Unauthorized');
}

Related, but unresolved posts:

My bad on this one.

Silly mistake. I was using ngrok to tunnel the webhook to my local machine and request.protocol is returning ‘http’, but the tunnel is using ‘https’.

Everything works when I explicitly set the webhook URL to the full URL that I set when defining the webhook.

Note: this is the full URL, NOT the path, i.e. https://youdomain.com/rapyd-webhook-endpoint

1 Like