dougmoscrop / serverless-http

Use your existing middleware framework (e.g. Express, Koa) in AWS Lambda 🎉
Other
1.72k stars 165 forks source link

Request body seems to be modified #195

Open MarcDeletang opened 3 years ago

MarcDeletang commented 3 years ago

Hello, first of all, thank you for this library, it is really nice to work with it and convert my express app !

However, I'm trying to get a webhook with stripe working and I have an issue when deploying to lambda. The method stripe.webhooks.constructEvent is rejecting the request (only when deployed to AWS, local dev works fine). I suspect that it's because the body is modified by something (API gateway, or serverless-http itself). I didn't find any issue referencing this so I wonder if anyone has encountered it before. I have tried to make this solution work: https://github.com/stripe/stripe-node/issues/356, but it doesn't fit well with what I got:

functions:
  app:
    handler: app/serverless.handler
    events:
      - http:
          path: stripe/hook
          method: post
          request:
            template:
              application/json: '{"rawBody": "$util.base64Encode($input.body)",
                "headers": {
                #foreach($param in $input.params().header.keySet())
                "$param": "$util.escapeJavaScript($input.params().header.get($param))"
                #if($foreach.hasNext),#end
                #end
                }}'
      - http: ANY /
      - http: "ANY {proxy+}"

Gives me this warning:

Serverless: Warning! You're using the AWS_PROXY in combination with a request configuration in your function "app". Only the request.parameters, request.schema configs are available in conjunction with AWS_PROXY. Serverless will remove this configuration automatically before deployment.

Do you have any advice to where should I look ? Ideally I would love to keep all of my controllers in the same http server and not manage multuple lambdas. If you need any help to "fix" this, feel free to ask !

dougmoscrop commented 3 years ago

Hey, I think this might be the cause: https://github.com/dougmoscrop/serverless-http/blob/master/lib/provider/aws/create-request.js#L38

It's probably too late for you - sorry, but you could try just even disabling that line in your local node_modules before you deploy, if that fixes it, we can talk about next steps

harunsmrkovic commented 3 years ago

I have exact same issue trying to use node-slack-sdk

  Error: Parsing request body prohibits request signature verification
harunsmrkovic commented 3 years ago

@dougmoscrop not sure if this line is the cause - I have tried returning

return event.body;

and

return Buffer.from(JSON.stringify(event.body));

neither of which work...

The type of req.body is string for me.

Looking at the line that throws in Slack SDK: https://github.com/slackapi/node-slack-sdk/blob/main/packages/events-api/src/http-handler.ts#L154

Seems like issue is the lack of rawBody 💥

🔧 Fix I've found is one of the following, either using serverless config:

module.exports.handler = serverless(app, {
  request(request) {
    request.rawBody = request.body;
  },
});

or using express.json body parser config:

app.use(express.json({
  verify: (req, res, buffer) => {
    req.rawBody = buffer
  }
}))
suciptoid commented 2 years ago

Thanks, @harunsmrkovic for pointing request.rawBody. This also fixed my nextjs server after found your solution.

In my case:

const app = next.getRequestHandler();

exports.handler = server(app, {
  request(request, event) {
    request.body = event.rawBody;
  },
});