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.
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?
Thanks in advance.
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
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.
You can install it by using npm install body-parser-rawbody
.
EDIT
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With