skip to Main Content

I try to implement a WooCommerce webhook functionality for feathers. To authenticate the request I need to verify the signature of the raw request body like so

const isSignatureValid = (
      secret: string,
      body: any,
      signature?: string
    ): boolean => {
      const signatureComputed = crypto
        .createHmac("SHA256", secret)
        .update(new Buffer(JSON.stringify(body), "utf8"))
        .digest("base64");

      return signatureComputed === signature ? true : false;
    };

Currently my signature never verifies. My guess is that this is due to the fact that req.body is not the acutual raw body of the request but some already parsed version with some featherjs goodness added.

Question is: How do I obtain the raw request body in a standard feathers app (created with feathers cli)?

3

Answers


  1. Chosen as BEST ANSWER

    Not sure if this is the most idiomatic way to do this, but I came up with the following:

    In of express.json() in the main app.ts file it is possible to add the raw, unparsed body to the req object. This is handy, as for some webhooks (woocommerce, stripe), you only need the raw body to verifiy the signature, but otherwise work with the parsed JSON.

    export interface IRequestRawBody extends http.IncomingMessage {
      rawBody: Buffer;
    }
    
    app.use(
      express.json({
        verify: (req: IRequestRawBody, res, buf) => {
          const rawEndpoints: string[] = ["/wc-webhook"];
    
          if (req.url && rawEndpoints.includes(req.url)) {
            req.rawBody = buf;
          }
        }
      })
    );
    

  2.   // Initialize our service with any options it requires
      app.use('/country', function (req, res, next) {
         console.log(req);
         next();
        }, new Country(options, app)
        );
    

    We can get request body as above in the express middleware of service class.

    Login or Signup to reply.
  3. This is an extension of the original answer from @florian-norbert-bepunkt since for me it didn’t work out of the box… I also needed a string version of the body in order to calculate the security hash.

    app.use(express.json({
       verify: (req, res, buf) => {
        const rawEndpoints = ["/someAPI"];
         
        if (req.url && rawEndpoints.includes(req.url)) {
          req.feathers = {dataRawBuffer: buf};
        }
      }
    }));
    

    After that, you can access the original buffer from context as

    context.params.dataRawBuffer
    

    I can confirm that this works on feathersJS v4, maybe this will help someone.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search