2015-05-12 65 views
3

我正在編寫一個自定義中間件,用於生成每個請求的加密簽名(與AWS API v4使用的身份驗證機制非常類似)。爲了正確生成這個簽名,我必須獲取HTTP請求的整個原始正文。如何在bodyparser之前訪問請求的原始主體?

我也使用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

您正在耗盡中間件中的請求流。當它到達bodyparser時,它現在會掛起,因爲它沒有流供它讀取,所以它永遠不會調用下一個。 http://stackoverflow.com/questions/18710225/node-js-get-raw-request-body-using-express http://stackoverflow.com/questions/9920208/expressjs-raw-body/9920700#9920700 – ThrowsException

+0

我知道這一點。問題是唯一可行的解​​決方案似乎是修改bodyParser源代碼,以便在Response中重新引入rawBody字段。 第一個解決方案導致了這一點,第二個解決方案現在不可行。 –

+0

不幸的是,這似乎是大多數人所做的。 – ThrowsException

回答

20

好吧,因爲解決這個問題的唯一可行的方法似乎是通過修改bodyParser的原始源代碼,我已經分叉它。

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}})) 

我還沒有親自試過這個選項,我不知道這是否作品。

+1

現在,這是服務 –

+0

我希望我能+ 100這個答案! –

相關問題