在request.pipe之前防止快速的body-parser移除主体

我正在尝试创build一个简单的快递中间件filter,它应该查看POST正文并确定是否应该将其传送到正确的服务器,或者是否被阻止。 如果我使用body-parser ,看起来我确实可以获得req.body ,但是当我将请求传递给另一个外部服务器时,它从请求中消失。

我试图解决这个问题的方法如下:

 //Router router.route('') .post(authController.isAuthenticated, urlHelper.bodyParser, //Without these two, everything pipes correctly urlHelper.filterBasedOnSomething, //Without these two, everything pipes correctly urlHelper.pipeToTrustedZone); 

在urlHelper中:

 const filterBasedOnSomething = function (req, res, next) { if (req.body && req.body.something === 'some string' && req.body.somethingElse === 'some other value') { return res.status(403).send("You shall not pass"); } else { next(); } } const pipeToTrustedZone = function (req, res) { //Here we are figuring out the correct forwarding url. This is simplified a little for the question, but it is well tested and works. var url = getProxiedPath(req.baseUrl) + req.originalUrl; req.pipe(request({ qs: req.query, uri: url }).on('error', function (err) { log.info(err); return res.sendStatus(400); })) .pipe(res); }; module.exports = { bodyParser: require('body-parser').json(), filterBasedOnSomething: filterBasedOnSomething, pipeToTrustedZone: pipeToTrustedZone, //.. } 

这似乎给我在我的filter方法req.body ,但身体消耗,并没有收到后,它已被pipe道。 我已经尝试了多个东西,像req.emit('data', JSON.stringify(req.body));req.write(.. ,但似乎都失败了。

有没有办法让我在查看请求主体之前进一步修改而不删除它? 或者我的方法是否存在inheritance问题?

我发现了多个github问题,并提出了与此有关的问题,但是我还没有成功地获得任何这些工作方法。

https://github.com/expressjs/body-parser/issues/74

在body-parser之前编写expression中间件来获得原始的请求体

https://github.com/expressjs/body-parser/issues/94

有没有办法让我在查看请求主体之前进一步修改而不删除它? 或者我的方法是否存在inheritance问题?

固有的问题是,你想先读一个stream,然后pipe它 – 即使stream已经被读取,它已经消失了。

你需要做的是在读取数据stream的时候caching数据stream,以便以后可以通过pipe道传输,或者从body-parser的输出中重构数据体。

但是你不能倒回一个stream,并再次开始阅读它,因为这意味着将所有的stream事件logging在内存中,而使用stream的常见优势是你不需要logging内存中的所有内容,只需处理一个data事件一次。

如果决定是否要pipestream可以基于身体外部的数据 – 如path或一些标题等 – 那么您可以使用身体分析器中间件仅用于那些不是pipe道的情况。

但是,如果决定是以身体的实际内容为基础的,那么你别无select,只能先阅读它 – 在这一点上,它不能再读取。

有几个模块可以帮助你:

但你可能会更好,通过parsing的身体分析器的输出重构的身体像这样的东西:

 request({ qs: req.query, uri: url, body: req.body, json: true }) 

并只pipe道响应。