Verifying requests
Learn about securing your incoming webhooks
We recommend verifying the webhook signature to make sure the data received is coming from Trengo.
The Trengo-Signature
header is sent with every webhook, it consists of a timestamp and hash concatenated together with a ;
in between.
Example signature: 1569508124;1298b36aefaeb7e0e93073744b954266515b69304b3dfe044cbf7203525061f4
The hash is a lowercase hexadecimal SHA256 HMAC digest of the timestamp, a .
and the request's body. It uses your signing secret as key.
Compare the hash part of the signature to verify the webhook's authenticity.
<?php
$payload = @file_get_contents('php://input'); // The request's body
$signature = $_SERVER['HTTP_TRENGO_SIGNATURE']; // The Trengo-Signature header value
$signingSecret = 'my-secret'; // Your signing secret
// verify the signature
if (verify($payload, $signature, $signingSecret)) {
echo 'Valid signature.';
} else {
echo 'Invalid signature';
}
/**
* @param $payload
* @param $signature
* @param $signingSecret
* @return bool
*/
function verify($payload, $signature, $signingSecret) {
list($timestamp, $hash) = explode(';', $signature);
return hash_equals(hash_hmac('sha256', $timestamp . '.' . $payload, $signingSecret), $hash);
}
var express = require('express');
var CryptoJS = require('crypto-js');
// start the express server
var app = express();
app.listen();
// parse the URLEncoded body and save the raw body to req.rawBody
app.use(
express.urlencoded({
verify: function (req, res, buf) {
req.rawBody = buf;
},
inflate: true,
type: "application/x-www-form-urlencoded"
})
);
// listen for POST requests to '/my-endpoint'
app.post('/my-endpoint', function(req, res) {
// replace with your signing secret, found in Trengo
var signingSecret = 'my-secret';
// get signature header
var signature = req.header('Trengo-Signature');
// get raw request body
var payload = req.rawBody;
// verify the signature
if (verify(payload, signature, signingSecret)) {
res.send('Valid signature');
// the parsed body is available at req.body
console.log(req.body);
} else {
res.send('Invalid signature');
}
});
// the function to verify the trengo-signature
function verify(payload, signature, signingSecret) {
// split the timestamp from the hash
var signatureParts = signature.split(';');
var timestamp = signatureParts[0];
var hash = signatureParts[1];
// get the raw digest bytes
var raw = CryptoJS.HmacSHA256(timestamp + '.' + payload, signingSecret);
// encode the raw bytes as hexadecimal digits
var hex = raw.toString(CryptoJS.enc.hex);
// and make the hexadecimal digits lowercase
var lowerCase = hex.toLowerCase();
// compare the result to the hash from the signature header
return lowerCase === hash;
}
Updated 3 months ago