7

Node.jsでnode-http-proxyを使用してプロキシを作成しようとしています。このプロキシは、リクエストがmongodbで承認されているかどうかを確認します。

基本的に、私は次のように使用するノード-http-プロキシ用のミドルウェアモジュールを作成しました。

httpProxy.createServer(
require('./example-middleware')(),
9005, 'localhost'
).listen(8005)

ミドルウェアモジュールが行うことは、mongojsを使用してmongodbに接続し、クエリを実行して、ユーザーがリソースへのアクセスを許可されているかどうかを確認することです。

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に非同期呼び出しを追加するとすぐにプロキシがハングし、応答が返されなくなることです。

明確にするために:「ユーザーが確認されていません」では、すべてが正常に機能し、403が返されます。「ユーザー確認済み」では、ログは表示されますが、ブラウザが永久にハングし、リクエストがプロキシされません。

ここで、コールバックの外で「ユーザー確認済み」とnext()の部分を削除すると、機能します。

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クエリは(当然のことながら)非同期で実行されることを意図しているため、それを行うことはできません。コールバックは、dbが応答したときにのみトリガーされます...

ミドルウェアを使用せずにバージョンを試しました。

http.createServer(function (req, res) {
  // run the async query here!
  proxy.proxyRequest(req, res, {
  host: 'localhost',
  port: 9000
});
}).listen(8001);

しかし、それも役に立ちませんでした...

どんな手掛かり?私はnode.jsを初めて使用するので、自分の側で誤解されているのではないかと思います...

4

2 に答える 2

6

答えが見つかりました。実際のキャッチは、リクエストをバッファリングする必要があるということです。

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);
于 2012-07-30T10:48:32.507 に答える
2

2つの問題:

  1. next();コールバックのelse場合は電話をかけていませんsort
  2. sortコールバックの2番目のパラメーターはCursor、ドキュメントの配列ではなく、です。そのため、docs.length > 0真になることはなく、コードは常にelseパスに従います。
于 2012-07-26T15:48:30.087 に答える