Webhook validation in Javascript/NodeJS

Tourist
16 0 2

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

0 Likes
Community Manager
Community Manager
618 45 81

Hi Leandro,

Are you saving data as a utf-8 encoded string? It looks like other people have had success this way. Let me know if you continue to have trouble.

0 Likes
New Member
2 0 1

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)
}
}

1 Like
Shopify Partner
1838 173 568

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.

I turn coffee in to code - since 1998
0 Likes
New Member
2 0 1

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?

0 Likes
Shopify Partner
1838 173 568

Check koa webhook middleware or express equivalent etc. Quite a few of these out in the wild.

I turn coffee in to code - since 1998
0 Likes

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 :)

Check out our newest app Daily Deals: https://apps.shopify.com/daily-deals-6
1 Like
Highlighted
Shopify Partner
24 1 1

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
}

 

0 Likes
New Member
4 0 0
    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 

0 Likes