这是一个典型的“不破坏已有功能”的故事。
我使用Node.js创建了一个相对简单的HTTP请求处理程序。我通过将请求正文的SHA-1与作为请求标头的签名进行匹配来进行请求验证:
当然,加密方法无法运行,因为
我添加了一些中间件:
我使用Node.js创建了一个相对简单的HTTP请求处理程序。我通过将请求正文的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
将结果转换为字符串。这允许加密方法运行,然而哈希和签名并不匹配!
当使用中间件如body-parser时,Express是否对请求体进行其他操作?这对我来说没有任何意义,但也许我错过了什么。