Hi,
Does anybody knows how to validate a webhook in Javascript?
I'm not sure if what it is being encoded its the request body as string or how. This is the code I have so far:
const digest = crypto
.createHmac('SHA256', sharedSecret)
.update(data)
.digest('base64');
console.info('isSameDigest', digest, hmac);
return digest === hmac;
"data" in this case its request.body
Thanks
Hello:
This is the NodeJs that I am using to validate the webhook, and it is not working. Can you provide any direction?
Thank you in advance.
const express = require('express')
const app = express()
const getRawBody = require('raw-body')
const crypto = require('crypto')
const bodyParser = require('body-parser');
const secretKey = 'SECRET KEY'
exports.webhookChecker = (req, res) => {
const webhook_hmac = req.get('X-Shopify-Hmac-SHA256')
// Create a hash using the body and our key
const hash = crypto
.createHmac('sha256', secretKey)
.update(JSON.stringify(req.body))
.digest('base64')
// Compare our hash to Shopify's hash
if (hash === webhook_hmac) {
// It's a match! All good
console.log('Webhook came from Shopify!');
res.sendStatus(200)
} else {
// No match! This request didn't originate from Shopify
console.log('Danger! Not from Shopify!')
res.sendStatus(403)
}
}
Try with
.update(JSON.stringify(req.body), 'utf8')
and also, doing a regular equality check isn't recommended as it leaves you vulnerable to timing attacks. Prefer to use safe-compare when checking the 2 hashes.
Looks okay otherwise.
Thank you Karl. I tried that, and it is still not working. I have verified that I am using the correct secret key, I still can't validate the test webhook. I will implement the safe-compare before I go live, thank you for the suggestion.
The Ruby and PHP examples reference $data, and I am assuming that the this is just what is returned by req.body. Is there anywhere, that you know of, that I can see exactly what I should be hashing?
Check koa webhook middleware or express equivalent etc. Quite a few of these out in the wild.
I can confirm that I'm getting the same error, I have similar code in my program:
verifyHmac(data, hmac) {
if (!hmac) {
return false;
} else if (!data) {
return false;
}
const calculatedSignature = crypto.createHmac('sha256', config.sharedSecret).update(data, 'utf8').digest('base64');
return calculatedSignature === hmac;
},
however, it still doesn't work. Any help :)
You need to use the following. You can validate this by generating a hash in liquid then validating with your function.
<script> {% assign my_secret_string = "no can defense the darce" | hmac_sha256: "protect ya neck fool" %} console.log('sha256 {{my_secret_string}}') </script>
function compare_sha256 (inbound_hmac, secret, str) => { console.log('secret, str', secret, str) var my_hmac = crypto.createHmac('sha256', secret).update(str).digest('hex') console.log('inbound_hmac', inbound_hmac, 'my_hmac', my_hmac) return inbound_hmac === my_hmac ? true : false }
let fnHash = resHeaders["x-shopify-hmac-sha256"]; let fnBody = JSON.stringify(data.body); let secretKey = ""; // All your webhooks will be signed with 0f009e8f22886da5b5cde06cb34bd7e411c9c1b06519a92800bd303f7188 so you can verify their integrity. let finalHash = crypto .createHmac('sha256', secretKey) .update(fnBody, 'utf8') .digest('base64'); log.info( finalHash, "!-----==========-----", fnHash);
my hash code also not matching for nodejs
Can someone guide me, Am I missing something @Busfox @KarlOffenberger
This one works for me, using express:
// Enable JSON use
app.use(bodyParser.json({
verify: (req, res, buf) => {
req.rawBody = buf;
},
}));
Then when compairing:
const hash = crypto.createHmac('sha256', SHOPIFY_APP_SECRET)
.update(Buffer.from(req.rawBody, 'utf8'))
.digest('base64');
User | Count |
---|---|
13 | |
12 | |
7 | |
6 | |
5 |