Hier werden viele Fragen gestellt, und obwohl die Fragen im Kontext von Node und passport.js gestellt werden, geht es bei den eigentlichen Fragen eher um den Workflow als darum, wie dies mit einer bestimmten Technologie geschehen soll.
Verwenden wir das @ Keith-Beispiel-Setup, das für zusätzliche Sicherheit etwas modifiziert wurde:
- Der Webserver von
https://example.com
dient einer einseitigen Javascript-Client-App
- RESTful Web Service at
https://example.com/api
bietet Serverunterstützung für Rich Client-Apps
- Server in Node und passport.js implementiert.
- Der Server verfügt über eine Datenbank (beliebiger Art) mit einer "Benutzer" -Tabelle.
- Benutzername / Passwort und Facebook Connect werden als Authentifizierungsoptionen angeboten
- Rich Client macht REST-Anfragen in
https://example.com/api
- Möglicherweise gibt es andere Clients (z. B. Telefon-Apps), die den Webdienst unter verwenden,
https://example.com/api
aber nichts über den Webserver unter wissen https://example.com
.
Beachten Sie, dass ich sicheres HTTP verwende. Dies ist meiner Meinung nach ein Muss für jeden Dienst, der offen verfügbar ist, da vertrauliche Informationen wie Kennwörter und Autorisierungstoken zwischen Client und Server übertragen werden.
Authentifizierung mit Benutzername / Passwort
Schauen wir uns zunächst an, wie die einfache alte Authentifizierung funktioniert.
- Der Benutzer stellt eine Verbindung zu her
https://example.com
- Der Server stellt eine umfangreiche Javascript-Anwendung bereit, die die Startseite rendert. Irgendwo auf der Seite befindet sich ein Anmeldeformular.
- Viele der Abschnitte dieser einseitigen App wurden nicht mit Daten gefüllt, da der Benutzer nicht angemeldet ist. Alle diese Abschnitte verfügen über einen Ereignis-Listener für ein "Anmelde" -Ereignis. All dies ist clientseitiges Zeug, der Server kennt diese Ereignisse nicht.
- Der Benutzer gibt sein Login und Passwort ein und klickt auf die Schaltfläche "Senden". Dadurch wird ein Javascript-Handler ausgelöst, der den Benutzernamen und das Passwort in clientseitigen Variablen aufzeichnet. Dann löst dieser Handler das "Login" -Ereignis aus. Auch dies ist alles eine clientseitige Aktion. Anmeldeinformationen wurden noch nicht an den Server gesendet .
- Die Listener des "Login" -Ereignisses werden aufgerufen. Jeder von diesen muss nun eine oder mehrere Anforderungen an die RESTful-API unter senden
https://example.com/api
, um die benutzerspezifischen Daten zu erhalten, die auf der Seite gerendert werden sollen. Jede einzelne Anfrage sie an den Webdienst sendet den Benutzernamen und das Passwort enthalten, möglicherweise in Form von HTTP - Basic - Authentifizierung, da der Dienst wird RESTful nicht erlaubt ist , Client - Zustand von einer Anfrage zur nächsten beizubehalten. Da sich der Webdienst auf sicherem HTTP befindet, wird das Kennwort während der Übertragung sicher verschlüsselt.
- Der Webdienst at
https://example.com/api
empfängt eine Reihe von Einzelanforderungen mit jeweils Authentifizierungsinformationen. Der Benutzername und das Kennwort in jeder Anforderung werden mit der Benutzerdatenbank verglichen. Wenn sie als korrekt befunden werden, wird die angeforderte Funktion ausgeführt und die Daten werden im JSON-Format an den Client zurückgegeben. Wenn Benutzername und Passwort nicht übereinstimmen, wird ein Fehler in Form eines 401-HTTP-Fehlercodes an den Client gesendet.
- Anstatt Clients zu zwingen, bei jeder Anforderung einen Benutzernamen und ein Kennwort zu senden, können Sie in Ihrem RESTful-Dienst eine Funktion "get_access_token" verwenden, die den Benutzernamen und das Kennwort verwendet und mit einem Token antwortet, bei dem es sich um eine Art kryptografischen Hash handelt, der eindeutig ist und einen gewissen Ablauf hat Datum damit verbunden. Diese Token werden mit jedem Benutzer in der Datenbank gespeichert. Anschließend sendet der Client das Zugriffstoken in nachfolgenden Anforderungen. Das Zugriffstoken wird dann anstelle des Benutzernamens und des Kennworts anhand der Datenbank überprüft.
- Nicht-Browser-Client-Anwendungen wie Telefon-Apps tun dasselbe wie oben. Sie fordern den Benutzer auf, seine Anmeldeinformationen einzugeben und diese dann (oder ein daraus generiertes Zugriffstoken) bei jeder Anforderung an den Webdienst zu senden.
Der wichtige Aspekt dieses Beispiels ist, dass RESTful-Webdienste bei jeder Anforderung eine Authentifizierung erfordern .
Eine zusätzliche Sicherheitsebene in diesem Szenario würde zusätzlich zur Benutzerauthentifizierung die Berechtigung für Clientanwendungen hinzufügen. Wenn beispielsweise der Webclient, iOS- und Android-Apps den Webdienst verwenden, möchte der Server möglicherweise wissen, welcher der drei Clients der Client einer bestimmten Anforderung ist, unabhängig davon, wer der authentifizierte Benutzer ist. Dadurch kann Ihr Webdienst bestimmte Funktionen auf bestimmte Clients beschränken. Hierfür können Sie API-Schlüssel und Geheimnisse verwenden. In dieser Antwort finden Sie einige Ideen dazu.
Facebook-Authentifizierung
Der obige Workflow funktioniert nicht für Facebook Connect, da die Anmeldung über Facebook einen Dritten hat, Facebook selbst. Für den Anmeldevorgang muss der Benutzer auf die Facebook-Website weitergeleitet werden, auf der Anmeldeinformationen außerhalb unserer Kontrolle eingegeben werden.
Mal sehen, wie sich die Dinge ändern:
- Der Benutzer stellt eine Verbindung zu her
https://example.com
- Der Server stellt eine umfangreiche Javascript-Anwendung bereit, die die Startseite rendert. Irgendwo auf der Seite befindet sich ein Anmeldeformular mit der Schaltfläche "Mit Facebook anmelden".
- Der Benutzer klickt auf die Schaltfläche "Mit Facebook anmelden". Dies ist nur ein Link, zu dem (zum Beispiel) umgeleitet wird
https://example.com/auth/facebook
.
- Die
https://example.com/auth/facebook
Route wird von passport.js verwaltet (siehe Dokumentation ).
- Der Benutzer sieht lediglich, dass sich die Seite ändert und sich nun auf einer von Facebook gehosteten Seite befindet, auf der er sich anmelden und unsere Webanwendung autorisieren muss. Dies liegt völlig außerhalb unserer Kontrolle.
- Der Benutzer meldet sich bei Facebook und gibt die Erlaubnis, unsere Anwendung, so dass Facebook nun zurück an die Callback - URL umleitet , dass wir in der passport.js Setup konfiguriert, die im Beispiel folgende Dokumentation ist
https://example.com/auth/facebook/callback
- Der passport.js-Handler für die
https://example.com/auth/facebook/callback
Route ruft die Rückruffunktion auf, die das Facebook-Zugriffstoken und einige Benutzerinformationen von Facebook empfängt, einschließlich der E-Mail-Adresse des Benutzers.
- Mit der E-Mail können wir den Benutzer in unserer Datenbank finden und das Facebook-Zugriffstoken damit speichern.
- Das Letzte, was Sie im Facebook-Rückruf tun, ist, zur Rich-Client-Anwendung zurückzukehren. Diesmal müssen wir jedoch den Benutzernamen und das Zugriffstoken an den Client übergeben, damit dieser sie verwenden kann. Dies kann auf verschiedene Arten erfolgen. Beispielsweise können Javascript-Variablen über eine serverseitige Vorlagen-Engine zur Seite hinzugefügt werden, oder es kann ein Cookie mit diesen Informationen zurückgegeben werden. (Vielen Dank an @RyanKimber für den Hinweis auf die Sicherheitsprobleme bei der Übergabe dieser Daten an die URL, wie ich ursprünglich vorgeschlagen hatte).
- Jetzt starten wir die Single-Page-App noch einmal, aber der Client hat den Benutzernamen und das Zugriffstoken.
- Die Clientanwendung kann das "Anmelde" -Ereignis sofort auslösen und die verschiedenen Teile der Anwendung die Informationen anfordern lassen, die sie vom Webdienst benötigen.
- Alle an gesendeten Anforderungen
https://example.com/api
enthalten das Facebook-Zugriffstoken zur Authentifizierung oder das eigene Zugriffstoken der Anwendung, das aus dem Facebook-Token über eine Funktion "get_access_token" in der REST-API generiert wird.
- Die Nicht-Browser-Apps haben es hier etwas schwieriger, da OAuth einen Webbrowser zum Anmelden benötigt. Um sich von einer Telefon- oder Desktop-App aus anzumelden, müssen Sie einen Browser starten, um die Weiterleitung zu Facebook durchzuführen, und noch schlimmer, Sie benötigen eine Möglichkeit für den Browser, das Facebook-Zugriffstoken über einen Mechanismus an die Anwendung zurückzugeben.
Ich hoffe, dies beantwortet die meisten Fragen. Natürlich können Sie Facebook durch Twitter, Google oder einen anderen OAuth-basierten Authentifizierungsdienst ersetzen.
Es würde mich interessieren, ob jemand einen einfacheren Weg hat, damit umzugehen.
passport-facebook
. Nachdem Sie dies zum Laufen gebracht haben, müssen Sie zunächst verstehen, wie Passport funktioniert und wie Anmeldeinformationen gespeichert werden. Einhaken es Restify oben ( siehe hier , um eine aktualisierte Version des von Ihnen erwähnen) würde einer der letzten Schritte sein (oder Sie können die REST - Schnittstelle in Express implementieren).