2012-07-26 5 views
7

Ich versuche, einen Proxy mit Knoten-http-Proxy in Node.js zu erstellen, die überprüft, ob eine Anfrage in einem Mongodb autorisiert ist.Aufrufen einer asynchronen Methode innerhalb einer Middleware in Knoten-http-Proxy

Im Grunde habe ich eine Middleware-Modul für den Knoten-http-Proxy, die ich wie folgt verwenden:

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

Was die Middleware-Modul tut, ist mongojs mit zu verbinden, eine Abfrage MongoDB und laufen zu sehen, ob der Benutzer berechtigt ist auf die Ressource zuzugreifen:

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(); 
    } 

}); 

} 
} 

das Problem ist jetzt, dass, sobald ich den asynchronen Aufruf hinzufügen mongojs die Proxy hängt MongoDB mit und nie wieder die Antwort senden.

Zur Verdeutlichung: Bei einem "User nicht bestätigt" funktioniert alles einwandfrei und der 403 wird zurückgegeben. Bei einem "user confirmed" sehe ich allerdings das Protokoll aber der Browser bleibt dann für immer hängen und die Anfrage wird nicht proxisiert.

Nun, wenn ich die entfernen „Benutzer bestätigt“ und next() teilweise außerhalb eines Rückrufes es funktioniert:

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(); 
} 

aber ich kann das nicht tun, da die mongojs Abfrage (zu Recht bedeutet, dass ich guess) asynchron ausgeführt werden, der Rückruf nur dann ausgelöst wird, wenn der db antwortet ...

ich habe auch versucht, die Version ohne eine Middleware:

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

Aber das hat nicht geholfen entweder ...

Irgendwelche Hinweise? Bitte beachte, dass ich bin neu node.js so vermute ich ein Missverständnis auf meiner Seite ...

+0

welche Middleware verwenden Sie? verbinden? –

Antwort

6

die Antwort gefunden, eigentlich der Haken ist, dass die Anforderung zwischengespeichert werden muss:

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); 
+0

Aber wie wäre es, dass in einer Middleware, als Proxy-Objekt, es immer noch nicht verfügbar ist (weil Middlewares geladen sind, bevor Sie die Funktion deklarieren, die das "Proxy" -Argument enthält)? – Mark

2

Zwei Probleme:

  1. Sie sind nicht next(); im else Fall Ihrer sort Rückruf aufrufen.
  2. Der zweite Parameter zu Ihrem sort Rückruf ist ein Cursor, kein Array von Dokumenten. Als solches ist docs.length > 0 niemals wahr und der Code folgt immer dem Pfad else.
+0

Hallo! Vielen Dank. Ich denke, meine Frage war nicht klar genug, also habe ich sie bearbeitet (mein Schlechter!). Ich habe eine Antwort in der else-Klausel schreiben (siehe neue Bearbeitungen) und der zweite Param der Sortierung ist ein Callback, kein Cursor, wie gesagt, ich benutze mongojs nicht den nativen mongo Javascript-Treiber (die Abfrage funktioniert gut). – domguinard

+0

Ah, kein Problem; Mein Fehler, dass ich den Proxy-Teil davon vermisse. Ist der dritte Parameter Ihrer Node-http-Proxy-Middleware-Funktion nicht ein "Proxy" -Objekt, keine "Next" -Funktion? https://github.com/nodejitsu/node-http-proxy/#setup-a-stand-alone-proxy-server-with-custom-server-logic – JohnnyHK

+0

Nun, anscheinend ist es eine next() Funktion. Ich habe versucht mit einem Proxy, aber es giert das gleiche Ergebnis: beide proxy.proxyRequest (req, res); und als nächstes(); Arbeiten außerhalb eines Rückrufs, aber nicht innerhalb. Der Proxy hängt immer noch ... – domguinard

Verwandte Themen