Javascript Node.js HTTP流式处理请求与Express.js请求对象
这是一个经典的故事“如果它没有坏,就不要修理它” 我使用Node.js创建了一个相对简单的HTTP请求处理程序。我通过将请求主体的SHA-1与作为请求标头的签名相匹配来验证请求:Javascript Node.js HTTP流式处理请求与Express.js请求对象,javascript,node.js,express,sha1,Javascript,Node.js,Express,Sha1,这是一个经典的故事“如果它没有坏,就不要修理它” 我使用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 =
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是否可能对请求主体执行其他操作?这对我来说没有任何意义,但也许我遗漏了一些东西。您在POST请求的正文中发送了什么 我已经用您的算法为这个字符串签名:
nodejs
,结果是:92fcfcfbcdbcdb06b40f76fee4e6271efc254290fd
然后我使用curl使用服务器:
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');
});
如果签名无效,您将看到一条消息,上面写着:
您没有权限
,但是如果您发送了有效的签名,您将能够使用POST路由/
找到解决方案。我刚刚创建了一个自定义主体解析器
function(req, res, next) {
req.setEncoding('utf8');
req.rawBody = '';
req.on('data', function(chunk) {
req.rawBody += chunk;
});
req.on('end', function(){
next();
});
}
我仍然不明白为什么bodyParser.text()不能以同样的方式工作 使用主体解析器
var options = {
inflate: true,
limit: '100kb',
type: 'application/octet-stream'
};
app.use(bodyParser.raw(options));
然后你可以用
app.post(routeName, (req, res) => {
let body = '';
req.on('data', (data) => {
body += data;
console.log(data)
});
req.on('end', () => {
fs.appendFile(`./${fileName}.log`, '\n' + body, (err) => {
if (err) throw err;
});
});
res.end();
})
如果正在使用请求流,则应使用fs.createWriteStream来写入文件。无论如何,感谢您指向bodyParser.raw。这是一个经典的故事,“如果它没有损坏,就不要修复它”,只要我们现在都已经吸取了教训。但我怀疑我永远不会。