Can't Verify Webhook authenticity

cmartin
Visitor
2 0 0

So I have tried multiple different methods to have my webhook requests authenticated here are a few with their errors

router.post("/shopify/webhook", async (req, res) => {
try {
await validShopifyRequest(shopSecret, req);
console.log("Authentic!");
} catch (err) {
console.log(err); // Simple example of error handling, this should really go in a log file or something
}
});

error

 

{ BadRequestError: request aborted
at IncomingMessage.onAborted (/www/tcg/tcgbe/node_modules/valid-shopify-request/node_modules/raw-body/index.js:231:10)
at emitNone (events.js:106:13)
at IncomingMessage.emit (events.js:208:7)
at abortIncoming (_http_server.js:424:9)
at socketOnEnd (_http_server.js:440:5)
at emitNone (events.js:111:20)
at Socket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
message: 'request aborted',
code: 'ECONNABORTED',
expected: null,
length: null,
received: 0,
type: 'request.aborted' }

 

async function verifyWebHook(req, res, next) {
try {
console.log("🎉 We got an order!");

// we'll compare the hmac to our own hash
const hmac = req.get("X-Shopify-Hmac-Sha256");
const body = await getRawBody(req);
// create a hash using the body and our key
const hash = crypto
.createHmac("sha256", shopSecret)
.update(body, "utf8", "hex")
.digest("base64");

// Compare our hash to Shopify's hash
if (hash === hmac) {
// It's a match! All good
console.log("Phew, it came from Shopifify!");
res.sendStatus(200);
} else {
// No match! This request didn't originate from Shopify
console.log("Danger! Not from Shopify!");
res.sendStatus(403);
}
} catch (e) {
console.log(e);
}
}

 

sam error as above

TypeError: Data must be a string or a buffer




async function verifyWebHook(req, res, next) {
try {
console.log("🎉 We got an order!");

// we'll compare the hmac to our own hash
const hmac = req.get("X-Shopify-Hmac-Sha256");

// create a hash using the body and our key
const hash = crypto
.createHmac("sha256", shopSecret)
.update(req.body, "utf8", "hex")
.digest("base64");

// Compare our hash to Shopify's hash
if (hash === hmac) {
// It's a match! All good
console.log("Phew, it came from Shopifify!");
res.sendStatus(200);
} else {
// No match! This request didn't originate from Shopify
console.log("Danger! Not from Shopify!");
res.sendStatus(403);
}
} catch (e) {
console.log(e);
}
}

 

 

 

ANY HELP IS AWESOME!!!

 

 

 

Replies 2 (2)

cmartin
Visitor
2 0 0

now im getting the 403 error so im closer 

 

router.post(
"/shopify/webhook",
bodyParser.json({
verify: function(req, res, buf, encoding) {
req.rawBody = buf;
}
}),
validateWebhook,
async (req, res) => {
console.log("holy **bleep** verified");
}
);
function validateWebhook(req, res, next) {
let buffme = Buffer.from(JSON.stringify(req.rawBody));
if (Buffer.isBuffer(buffme)) {
console.log("BUFFER DIS ASS");
}
generated_hash = crypto
.createHmac("sha256", shopSecret)
.update(buffme)
.digest("base64");
if (generated_hash == req.headers["x-shopify-hmac-sha256"]) {
next();
} else {
console.log("**bleep**");
res.sendStatus(403);
}
}
kyle_truong
Shopify Partner
59 6 16

My webhook verifying middleware works for me and it looks almost like yours, maybe it'll help:

 
import * as crypto from 'crypto';

export const verifyWebhook = async (
  ctx: AppContext,
  next: () => Promise<any>,
) => {
  const shopifyHmac = ctx.request.headers['x-shopify-hmac-sha256'];

  if (!shopifyHmac) {
    logError(new Error(), ERROR_MESSAGE.MISSING_SHOPIFY_HMAC, ctx);
    ctx.throw(400, getStatusText(400));
  }

  const hmac = crypto
    .createHmac('sha256', process.env.SHOPIFY_API_SECRET)
    .update(ctx.request.rawBody)
    .digest('base64');

  if (hmac !== shopifyHmac) {
    logError(new Error(), ERROR_MESSAGE.HMAC_VALIDATION_FAILED, ctx);
    ctx.throw(400, getStatusText(400));
  }

  await next();
};