18

I need the raw request body to be able to SHA-1 digest it to validate the Facebook webhook X-Hub-Signature header that's passed along with the request to my Firebase Function (running on Google Cloud Functions).

The problem is that in cases like this (with a Content-Type: application/json header) GCF automatically parses the body using bodyParser.json() which consumes the data from the stream (meaning it cannot be consumed again down the Express middleware chain) and only provides the parsed javascript object as req.body. The raw request buffer is discarded.

I have tried to provide an Express app to functions.https.onRequest(), but that seems to be run as a child app or something with the request body already being parsed, just like when you pass a plain request-response callback to onRequest().

Is there any way to disable GCF from parsing the body for me? Or could I somehow specify my own verify callback to bodyParser.json()? Or is there some other way?

PS: I first contacted Firebase support about this a week ago, but for lack of a response there I'm trying it here now.

4

3 回答 3

30

Now you can get the raw body from req.rawBody. It returns Buffer. See documentation for more details.

Thanks to Nobuhito Kurose for posting this in comments.

于 2018-05-14T20:47:06.237 回答
4

Unfortunately the default middleware currently provides no way to get the raw request body. See: Access to unparsed JSON body in HTTP Functions (#36252545).

于 2017-03-22T18:07:35.447 回答
0
 const escapeHtml = require('escape-html');

/**
 * Responds to an HTTP request using data from the request body parsed according
 * to the "content-type" header.
 *
 * @param {Object} req Cloud Function request context.
 * @param {Object} res Cloud Function response context.
 */
exports.helloContent = (req, res) => {
  let name;

  switch (req.get('content-type')) {
    // '{"name":"John"}'
    case 'application/json':
      ({name} = req.body);
      break;

    // 'John', stored in a Buffer
    case 'application/octet-stream':
      name = req.body.toString(); // Convert buffer to a string
      break;

    // 'John'
    case 'text/plain':
      name = req.body;
      break;

    // 'name=John' in the body of a POST request (not the URL)
    case 'application/x-www-form-urlencoded':
      ({name} = req.body);
      break;
  }

  res.status(200).send(`Hello ${escapeHtml(name || 'World')}!`);
};
于 2020-11-26T23:28:16.437 回答