Sending a request with HMAC SHA256 signature using Postman

Make debugging easier by generating signatures right within Postmark.

Today I was working on Flare, fixing a bug where a webhook payload didn't work. Webhooks allow applications to communicate with each other without constant polling for updates. When a change happens, a request is sent from one service to another, indicating what happens.

The web is an open place with many bad actors, so a signature is sent with this request as a protection measure. This signature is constructed from a secret key that both sender and receiver know and the contents of the payload.

In PHP, the sender would create a request and then a signature as follows:

$signature = hash_hmac(
 'sha256',
 $payload,
 'some_secret_key'
);

This signature is then appended as a header to the request.

The receiver on the other side would then again construct the signature like above and then check if it corresponds with the signature sent:

hash_equals($request->header('signature'), $signature);

If the two correspond, we know no one tampered with the message, and the request was sent by the service we trust (not some other bad actor who found out what the endpoint was).

Local signature mess

That's all great. Until you start debugging errors why something is not working, Postman is one of the best tools to send API requests from your computer when you're debugging.

But since the signature depends on the contents of the request payload, it needs to be recalculated each time the payload changes.

Luckily Postman has a solution for this! It is possible to run some JavaScript code before the request is sent, which allows you to change the request right before it is sent out. You can write this code within the "Pre-request Script" tab:

To add a signature header, we use this piece of code:

const secret ='some_secret_key';

var signature = CryptoJS.HmacSHA256(request.data, secret).toString(CryptoJS.digest);

pm.request.addHeader({
 key: 'signature',
 value: signature
});

console.log("Signature :: " + signature)

This code will add a signature header with an HMAC SHA256 hashed version of the secret and payload content, neat!