2015-07-09 129 views
1

這是一類的故事,「如果沒壞,就不要修理它」Node.js的HTTP流與Express.js請求對象請求

我創造了使用相對簡單的HTTP請求處理程序Node.js的我對請求主體的SHA-1的匹配到是作爲一個請求頭簽名驗證請求:

var http = require('http'); 
var crypto = require('crypto'); 
var secret = process.env.MY_SECRET; 

var requestListener = function(req, res) { 
    if (req.method === 'POST') { 
     var body = ''; 
     req.on('data', function(data) { 
      body += data; 
     }); 
     req.on('end', function() { 
      var signature = req.headers['x-signature']; 
      var hash = crypto.createHmac('sha1', secret) 
       .update(body) 
       .digest('hex') 
       .toUpperCase(); 
      if (signature === hash) { 
       // request is authorized 
      } 
     }); 
    } 
}; 

var server = http.createServer(requestListener); 
server.listen(3000); 

這工作得很好,但一切都是醜陋的,到處都是Express.js我的其他功能反正要實施。我重寫了代碼如下:

var crypto = require('crypto'); 
var express = require('express'); 
var app = express(); 
var secret = process.env.MY_SECRET; 

app.use(function(req, res, next) { 
    var signature = req.get('x-signature'); 

    var hash = crypto.createHmac('sha1', secret) 
     .update(req.body) 
     .digest('hex') 
     .toUpperCase(); 

    if (signature === hash) { 
     next(); 
    } else { 
     // unauthorized 
    }  
}); 

app.post('/', function(req, res) { 
    // request is authorized 
}); 

app.listen(3000); 

當然,加密方法將無法運行,因爲req.body現在既不是字符串或緩衝區。但我該如何解決這個問題?

我包括一些中間件:

app.use(bodyParser.json()); 

然後用JSON.stringify將結果轉換爲字符串。這允許加密方法運行,但是散列和簽名不匹配!

當使用中間件身體分析器時,Express是否可能對請求主體做其他事情?這對我沒有任何意義,但也許我錯過了一些東西。

回答

0

你在POST請求的主體中發送了什麼?

我已經簽署了這個字符串:nodejs有你的算法,結果是:92FCFCFBCDB06B40F76FEE4E6271EFC2554290FD

然後我消耗,捲曲服務器:

curl --header "x-signature: 92FCFCFBCDB06B40F76FEE4E6271EFC2554290FD" --data "something=nodejs" http://localhost:4040 

這是我的服務器上的文件:

var express = require('express'); 
var app = express(); 

var bodyParser = require('body-parser'); 

var secret = 'something'; 
var crypto = require('crypto'); 

app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({extended: true})); 

app.use(function(req, res, next) { 
    var signature = req.get('x-signature'); 
    var hash = crypto 
    .createHmac('sha1', secret) 
    .update(req.body.something) 
    .digest('hex') 
    .toUpperCase(); 

    if (signature === hash) { 
    next(); 
    } else { 
    res.send('you do not have permission'); 
    } 
}); 

app.post('/', function(req, res) { 
    res.send('hey'); 
}); 

app.listen(4040, function() { 
    console.log('server up and running at 4040 port'); 
}); 

如果簽名無效,您將看到一條消息:you do not have permission但如果您發送有效簽名,您將能夠消耗POST路線/

0

找到了解決辦法。我剛創建了一個自定義身體分析器。

function(req, res, next) { 
    req.setEncoding('utf8'); 
    req.rawBody = ''; 
    req.on('data', function(chunk) { 
     req.rawBody += chunk; 
    }); 
    req.on('end', function(){ 
     next(); 
    }); 
} 

我還是不明白爲什麼bodyParser.text()不能以相同的方式工作!