Next() not working in middlware when verifying Webhook

chris_pappen
Shopify Partner
14 0 4

I'm using the Shopify CLI with NodeJS, React und MongoDB. When verifying webhooks coming from Shopify I experience a weird behavior.

My middleware:

import validShopifyRequest from "valid-shopify-request";

export const verifyWebhook = async (ctx, next) => {
  try {
    await validShopifyRequest(process.env.SHOPIFY_API_SECRET, ctx.req);

    //
    await next();
  } catch (err) {
    console.log(err);
    ctx.throw(401, "Access denied! (HMAC)");
  }
};

For some reason the next() call is not executed. But when I leave out the verification step with 'validShopifyRequest' it is working fine.

 

Any ideas what might be going on here?

 

Thank you so much!

Chris

 

Replies 5 (5)

_JCC_
Shopify Staff
200 27 55

Chris,

I wanted to follow-up on with this post. You and I were in discussion on a somewhat related post, where you had replied to me on the 29th of December saying things were good. Given the date of this post I wanted to check-in and see if you got this sorted out as well.

Regards,

John

John C | Developer Support @ Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

chris_pappen
Shopify Partner
14 0 4

Hi John,

Not really...I suspect that the body parser is causing some issues. The HMAC signature is generated through the raw request body. The preinstalled Koa-Router or perhaps another package coming with the Shopify CLI is parsing the body. 

However, that's only an assumption. Right now I'm looking for a developer who can help me wit this. Two developers failed already. I can't understand that other devs don't have the same problem using the Shopify CLI. I guess most don't verify the webhook call.

Any chance who could look into this?

Chris

GrowthSteam
New Member
5 0 0

I have a (somewhat) similar problem. I was using a few webhooks, subscribing to them using the GraphQL API. And it is working fine for, e.g. APP_SUBSCRIPTIONS_UPDATE. I added another subscription, to ORDERS_PAID this time.

The funny thing is, that I am using the same method for verification, but it fails on ORDERS_PAID, where it works just fine on APP_SUBSCRIPTIONS_UPDATE.

In order to get it working in the first place I had to bypass body parsing for webhook endpoints. You can do this before other middle-wares take your request, and everything works fine then.

My question would be, is there a difference in how those 2 hooks should be verified, or is there bug in my code?

chris_pappen
Shopify Partner
14 0 4

Hi there,

although I can't answer your question about the difference between the two webhooks I'd like to ask if you could share your code about dealing with the body parser so the webhook handler is called correctly?

 

Thanks

Chris

GrowthSteam
New Member
5 0 0

Yes, of course! (Sorry for the late reply)

So, what happens is that body parser(s) (may) change the original content passed on to by shopify, thus validation fails afterwards. In order to avoid this, I'm simply storing the original value in a separate variable. I register body parser like so:

 

 

app.use(bodyParser.json({
  verify (req, res, buf) {
    if (/^\/webhooks/.test(req.originalUrl)) {
      req.textBody = buf.toString()
    }
  }
}))

 

This effectively catches my routes which are handling webhooks with a regex, and stores string buffer to a new variable in my request called 'textBody'

Hope it helps!