如何在Google Cloud功能中获取原始请求正文?

时间:2017-03-22 11:37:48

标签: javascript firebase google-cloud-functions

我需要原始请求主体能够通过SHA-1消化来验证Facebook webhook X-Hub-Signature标头,该标头随请求传递给我的Firebase功能(在Google Cloud Functions上运行)。

问题是在这种情况下(带有Content-Type: application/json标题)GCF会自动使用bodyParser.json()解析正文,这会消耗流中的数据(这意味着它不能再次在Express中间件中使用链)并且仅将解析的javascript对象提供为req.body。原始请求缓冲区被丢弃。

我试图向functions.https.onRequest()提供一个Express应用程序,但这似乎是作为子应用程序运行的,或者已经解析了请求正文的东西,就像你传递一个普通的请求 - 响应回调一样onRequest()

有没有办法禁用GCF为我解析身体?或者我可以以某种方式指定我自己verify回调bodyParser.json()?或者还有其他方式吗?

PS:我一周前第一次联系Firebase支持,但由于缺乏响应,我现在在这里尝试。

3 个答案:

答案 0 :(得分:13)

现在您可以从req.rawBody获取原始身体。它返回Buffer。有关详细信息,请参阅documentation

感谢Nobuhito Kurose在comments发布此内容。

答案 1 :(得分:4)

不幸的是,默认的中间件目前无法获取原始请求正文。请参阅:Access to unparsed JSON body in HTTP Functions (#36252545)

答案 2 :(得分: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')}!`);
};