在node-http-proxy的中间件内部调用异步方法 [英] Invoking an asynchronous method inside a middleware in node-http-proxy
问题描述
我正在尝试使用Node.js中的node-http-proxy创建一个代理,以检查请求是否在mongodb中得到了授权.
I'm trying to create a proxy with node-http-proxy in Node.js that checks whether a request is authorized in a mongodb.
基本上,我为我使用的node-http-proxy创建了一个中间件模块:
Basically, I created a middleware module for the node-http-proxy that I use like this:
httpProxy.createServer(
require('./example-middleware')(),
9005, 'localhost'
).listen(8005)
中间件模块所做的是使用mongojs连接到mongodb并运行查询以查看用户是否有权访问该资源:
What the middleware module does is using mongojs to connect to mongodb and run a query to see if the user is authorized to access the resource:
module.exports = function(){
// Do something when first loaded!
console.log("Middleware loaded!");
return function (req, res, next) {
var record = extractCredentials(req);
var query = -- Db query --
//Debug:
log("Query result", query);
db.authList.find(query).sort({
"url.len": -1
}, function(err, docs){
console.log(docs);
// Return the creator for the longest matching path:
if(docs.length > 0) {
console.log("User confirmed!");
next();
} else {
console.log("User not confirmed!");
res.writeHead(403, {
'Content-Type': 'text/plain'
});
res.write('You are not allowed to access this resource...');
res.end();
}
});
}
}
现在的问题是,一旦我使用mongojs将异步调用添加到mongodb中,代理就会挂起并且永远不会将响应发送回去.
Now the problem is that as soon as I add the asynchronous call to mongodb using mongojs the proxy hangs and never send the response back.
为了澄清:在未确认用户"上,一切正常,并且返回了403.在用户确认"上,我看到了日志,但浏览器随后永久挂起,该请求未得到代理.
To clarify: on a "User not confirmed" everything works fine and the 403 is returned. On a "user confirmed" however I see the log but the browser then hangs forever and the request isn't proxied.
现在,如果我在回调之外删除用户确认"和next()部分,它将起作用:
Now, if I remove the "user confirmed" and next() part outside of a callback it does work:
module.exports = function(){
// Do something when first loaded!
console.log("Middleware loaded!");
return function (req, res, next) {
var record = extractCredentials(req);
var query = --- query ---
console.log("User confirmed!");
next();
}
但是我不能这样做,因为(正确地我想)mongojs查询是要异步执行的,只有在数据库回复时才触发回调.
but I can't do that since the mongojs query is meant (rightfully I guess) to be executed asynchronously, the callback being triggered only when the db replied...
我也尝试了不使用中间件的版本:
I also tried the version without using a middleware:
http.createServer(function (req, res) {
// run the async query here!
proxy.proxyRequest(req, res, {
host: 'localhost',
port: 9000
});
}).listen(8001);
但这也无济于事...
But that did not help either...
有任何线索吗?请注意,我是node.js的新手,所以我怀疑自己的误会...
Any clue? Note that I'm new to node.js so I suspect a misunderstanding on my side...
推荐答案
找到了答案,实际上要注意的是请求需要缓冲:
Found the answer, actually the catch is that the request needs to be buffered:
httpProxy.createServer(function (req, res, proxy) {
// ignore favicon
if (req.url === '/favicon.ico') {
res.writeHead(200, {
'Content-Type': 'image/x-icon'
} );
res.end();
console.log('favicon requested');
return;
}
var credentials = extractCredentials(req);
console.log(credentials);
var buffer = httpProxy.buffer(req);
checkRequest(credentials, function(user){
if(user == ...) {
console.log("Access granted!");
proxy.proxyRequest(req, res, {
host: 'localhost',
port: 9005,
buffer: buffer
});
} else {
console.log("Access denied!");
res.writeHead(403, {
"Content-Type": "text/plain"
});
res.write("You are not allowed to access this resource...");
res.end();
}
});
}).listen(8005);
这篇关于在node-http-proxy的中间件内部调用异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!