在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道响应。