Erstellen Sie eine sichere oauth-API mit passport.js und express.js (node.js)

Ich denke, ich habe ein spezifisches Problem, es sei denn, ich mache die Dinge nicht richtig.

Ich habe eine Anwendung mit 2 Seiten, einen Client (HTML-Site) und eine API (erstellt mit Express + Mongodb). Auf die API muss sicher zugegriffen werden. Beide befinden sich in unterschiedlichen Domains. Angenommen, meine Website befindet sich auf domain.com und meine API auf api.com:3000.

Ich habe einen Reisepass hinzugefügt, um ein Zugriffstoken von Github zu erhalten, während ich meine Benutzer mit ihren Daten erstelle, damit ich mich grundsätzlich bei Github anmelden kann.

Mein aktueller Prozess ist:

1) Der Client (die Site) öffnet ein Popup auf der API

window.open("http://api.com:3000/oauth")

2) Der Express-Server, starten Sie den Pass-Prozess:

app.get('/oauth', passport.authenticate('github'), function(req, res) {

});

Für die Strategie habe ich verwendetdieser Code.

3) Ich leite den Rückruf an eine URL weiter, die das Popup schließt (Javascript mit einem window.close ()):

app.get('/oauth/callback', passport.authenticate('github', { failureRedirect: '/' }), function(req, res) {
    res.redirect('/auth_close');
});

An diesem Punkt ist alles in Ordnung, ich bin jetzt in der API angemeldet. Mein Problem ist, wie ich Daten zum Client zurückbringe, da der Client noch nichts über accessToken, Benutzer oder Benutzer-ID weiß.

Also habe ich vom Client (der Site, die das Popup öffnet) aus verschiedene Ansätze ausprobiert:

Abrufen eines Werts aus dem Popup: Funktioniert aufgrund der Umleitung nicht, ich verliere den Überblick über die Javascript-Informationen des Popups

Aufrufen meiner API, um den "aktuellen Benutzer" in der Sitzung abzurufen, zhttp://api.com:3000/current Noch eine Bitte, nicht ideal, aber diese funktioniert. Ich habe jedoch immer noch ein Problem.

Diese / aktuelle URL gibt den Benutzer zurück, wenn ich sie vom Browser aus erreiche, da der Browser in der Kopfzeile das Express-Sitzungscookie anfordert:

Cookie:connect.sid=s%3AmDrM5MRA34UuNZqiL%2BV7TMv6.Paw6O%2BtnxQRo0vYNKrher026CIAnNsHn4OJdptb8KqE

Das Problem ist, dass ich diese Anfrage von jquery oder ähnlichem stellen muss, und das ist, wo es fehlschlägt, weil die Sitzung nicht gesendet wird. So wird der Benutzer nicht zurückgegeben:

app.get('/current', function() {
    // PROBLEM HERE, req.user is undefined with ajax calls because of the session!
});

Ich habe eine Möglichkeit gefunden, dies zum Laufen zu bringen, bin aber nicht zufrieden damit, da ich Probleme mit CORS-Cross-Browsern habe. Dies fügt Folgendes hinzu:

res.header("Access-Control-Allow-Credentials", "true");

Fügen Sie das withCredentials-Feld in einem jquery-Ajax-Aufruf hinzu, wie erläutertHier.

Eine Zuordnung von Feldname-Feldwert-Paaren, die für das native XHR-Objekt festgelegt werden sollen. Sie können es beispielsweise verwenden, um withCredentials für domänenübergreifende Anforderungen auf true zu setzen, falls dies erforderlich ist.

$.ajax({
   url: a_cross_domain_url,
   xhrFields: {
      withCredentials: true
   }
});

Ich bin auch nicht zufrieden damit, da ich den Platzhalter in meinem Header verliere:Access-Control-Allow-OriginIch muss eine Domain angeben, wie erklärtHier.

Ich bin mir also nicht sicher, wie ich vorgehen soll. Das einzige, was ich brauche, ist, dass der Client entweder ein accessToken oder eine userID vom Passport-Oauth-Prozess zurückerhält. Die Idee ist, dieses Token in jedem Aufruf der API zu verwenden, um die Aufrufe zu validieren.

Irgendeine Ahnung?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage