在bodyparser之前如何访问请求的原始内容? [英] How to access the raw body of the request before bodyparser?

查看:92
本文介绍了在bodyparser之前如何访问请求的原始内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个自定义中间件,该中间件为每个请求生成一个加密签名(这与AWS API v4所使用的身份验证机制非常相似).为了正确生成此签名,我必须获取HTTP请求的整个原始正文.

I am writing a custom middleware that generates a cryptographic signature of every request (it is very similiar to the authentication mechanism used by AWS API v4). In order for this signature to be correctly generated, I must fetch the entire raw body of the HTTP request.

我还在使用BodyParser,它是在自定义中间件之后注册的.

I am also using BodyParser, which is registered after my custom middleware.

我的自定义中间件可以这样表示:

My custom middleware can be represented like this:

// libs/simplifiedSignatureCheckerMiddleware.js

module.exports = function (req, res, next){

// simple and fast hashing stuff

var payload = '';
req.on('data', function(chunk) { payload += chunk }, null);
req.on('end', function(){

    // hmac stuff

    console.log(payload);

    var ok = true; // ...

    if(ok)
        next();
    else
        next("Bad")
});

}

这就是我在服务器上使用它的方式.

This is how I use it on the server.

// simpleServer.js

// BASE SETUP
// =============================================================================
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var jsonStream = require('express-jsonstream');
var nconf = require('nconf');
var https = require('https');
var fs = require('fs');

// load configurations
nconf.argv().env();
nconf.file({file: 'config.json'});

app.use(require('./libs/simplifiedSignatureCheckerMiddleware'));

// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(jsonStream());

// ROUTES FOR API
// =============================================================================
var router = express.Router();

router.post('/api/', function (req, res) {
    var param1 = req.body.param1 || "";
    var param2 = req.body.param2 || "";

    res.json({message: 'welcome', one: param1, two: param2 });
});
// REGISTER ROUTES
app.use(router);

// START THE SERVER
// =============================================================================

https.createServer({
    key: fs.readFileSync('./key.pem'),
    cert: fs.readFileSync('./cert.pem')
}, app).listen(nconf.get('http:port'));

console.log("APIs listening on port " + nconf.get('http:port'));

您可以验证,原始内容已由中间件成功写入控制台,但该请求将永远不会被注册的路由处理,并且连接将永远挂起.

As you can verify, the raw body is written successfully to the console by the middleware, BUT the request will never be processed by the registered route and the connection hangs forever.

您是否有解决此问题的线索?

Do you have any clue on how to solve this problem?

谢谢.

推荐答案

好吧,因为解决此问题的唯一可行方法似乎是通过修改bodyParser的原始源代码,所以我将其分叉.

Ok, since the only feasible way to solve this problem seems to be by modifying the original source code of bodyParser, I have forked it.

https://github.com/emanuelecasadio/body-parser-rawbody

此派生将请求的原始正文公开为一个名为rawBody的字段.如您所见,只有一行额外的代码.

This fork exposes the raw body of the request as a field named rawBody. As you can see, there is only ONE extra line of code.

您可以使用npm install body-parser-rawbody进行安装.

编辑

另一种选择是使用这样的bodyParser,如dougwilson在此处指出的: https://github.com/expressjs/body-parser/issues/83#issuecomment-80784100

Another option is to use the bodyParser like this, as noted by dougwilson here: https://github.com/expressjs/body-parser/issues/83#issuecomment-80784100

app.use(bodyParser.json({verify:function(req,res,buf){req.rawBody=buf}}))

我还没有亲自尝试过此选项,也不知道它是否有效.

I haven't personally tried this option and I do not know if it works.

这篇关于在bodyparser之前如何访问请求的原始内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆