2015-07-09 135 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()不能以相同的方式工作!