Express 4.17 get raw body for one endpoint

Viewed 1929

I am trying to implement Stripe in my web API and need to read the raw body of the request. I already have existing API paths in my application that does NOT need the raw body.

The code I have implemented is based Stripe documentation example, see below.

const stripe = require('stripe')('apikey...');
const endpointSecret = 'whsec_...';

const express = require('express');
const app = express();
app.post('/webhook', express.raw({type: 'application/json'}), (request, response) => {
  let event = request.body;
  console.log('body', event);
  const headers = JSON.stringify(request.headers);
  console.log('Headers', headers);
  // Only verify the event if you have an endpoint secret defined.
  // Otherwise use the basic event deserialized with JSON.parse
  if (endpointSecret) {
    // Get the signature sent by Stripe
    const signature = request.headers['stripe-signature'];
    try {
      event = stripe.webhooks.constructEvent(request.body, signature, endpointSecret);
    } catch (err) {
      console.log(`⚠️  Webhook signature verification failed.`, err.message);
      return response.sendStatus(400);
    }
  }

  // Handle the event
  ...
  // Return a 200 response to acknowledge receipt of the event
  response.send();
});

app.listen(443, () => console.log('Running on port 443'));

This code logs the below messages - since the raw body is empty.

body
Headers {"host":".....}
⚠️ Webhook signature verification failed. No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing

I have tried to fix this by adding a middleware to read the raw body.

// Custom middleware that keeps the raw request body. This is needed for Stripe
app.use((req, res, next)=>{
  req.rawBody = '';
  req.on('data', (chunk) => { req.rawBody += chunk; });
  req.on('end', () => {
    try {
      req.body = JSON.parse(req.rawBody);
      next();
    } catch (err) {
      console.log('Error parsing body')
      next();
    }
   });
 });

app.post('/webhook', (request, response) => {
  let event = request.body;
  console.log('rawBody', request.rawBody)
  if (endpointSecret) {
    // Get the signature sent by Stripe
    const signature = request.headers['stripe-signature'];
    try {
      event = stripe.webhooks.constructEvent(request.rawBody, signature, endpointSecret);
    } catch (err) {
      console.log(`⚠️  Webhook signature verification failed.`, err.message);
      return resp.sendStatus(400);
    }

According to logging the raw body is still empty. I still get the same error message in console.

How can I add the raw body to the request? Preferably using a middleware. Kind regards /K

UPDATE: (Thanks Bravo!) The below code seems to work by exposing the raw body

app.post('/webhook', express.raw(), (request, response) => {
      let event = request.rawBody;
0 Answers
Related