当前位置: 首页 > 知识库问答 >
问题:

如何在bodyparser之前访问请求的原始正文?

宋耀
2023-03-14

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

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

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

// 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")
});

}

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

// 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'));

正如您可以验证的那样,中间件已将原始主体成功写入控制台,但请求将永远不会由注册的路由处理,连接将永远挂起。

你对如何解决这个问题有什么线索吗?

提前谢谢。

共有1个答案

夏晋
2023-03-14

好的,由于解决这个问题的唯一可行方法似乎是修改body Parser的原始源代码,因此我已经分叉了它。

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

您可以使用npm install body parser rawbody安装它。

编辑

另一种选择是使用如下bodyParser,如dougwilson所述:https://github.com/expressjs/body-parser/issues/83#issuecomment-80784100

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

我没有亲自尝试过这个选项,我不知道它是否有效。

 类似资料:
  • 我正试图根据API验证自己。这个API使用来自请求的原始主体来创建哈希,它将使用该哈希对我的令牌进行身份验证。 出于测试目的,我使用postman和一个请求前脚本来创建哈希。一切都很好,只有一个例外: 在代码选项卡中,我有 谢了!

  • 我想在原始负载被反序列化为POJO之前访问它(在我的例子中是Json主体)。 我的控制器有一个带有如下签名的方法。 更新。谢谢你指导我正确的资源。我使用了下面的解决方案,效果很好。添加已成功。但请注意,应启用。

  • 我使用下面的代码来处理一个临时SQLite表: 将数据保存到临时:

  • 我有一个Twilio无服务器函数,它处理来自另一个通过JWT提供身份验证的系统的请求。为了解码用JWT编码的请求,我需要获得原始请求正文。根据Twilio功能文档(https://www.twilio.com/docs/runtime/functions/invocation)国家: 事件对象包含传递到函数中的请求参数。POST和GET参数都将折叠到同一个对象中。对于POST请求,您可以传递表单编

  • 这个问题以前可能有人问过,但没有,没有得到明确的回答。具体如何将原始的整个JSON发布到一个修改请求的主体中? 在这里见类似的问题。或者这个答案是正确的,它必须是表单url编码并作为字段传递?我真的希望不是这样,因为我连接到的服务只是希望文章正文中有原始的JSON。它们并不是为了寻找JSON数据的特定字段而设置的。 我只想和restperts一劳永逸地澄清这一点。一人回答不用改装。另一个不确定句法

  • 问题内容: 在执行ModelForm时,我想根据当前用户是否为超级用户执行不同类型的验证检查。如何访问当前的请求用户? 问题答案: 您可以将用户对象作为额外的参数传递给表单构造函数。 例如 构造函数将如下所示: 然后根据需要在clean_XX表单中使用user