JWT Token-Strategie für das frontend und backend
Bin ich eine Anwendung schreiben, die mit einem vorderen Ende in emberjs und backend/server-Seite in einem nodejs-server. Ich habe emberjs so konfiguriert, dass ein Benutzer-login/signup mit einem 3rd-party-Oauth (google, twitter, Facebook). Ich habe ein backend geschrieben express nodejs-server, dass hosts die RESTful APIs.
Ich habe keine DB verbunden emberjs und ich glaube nicht, ich sollte sowieso, da es streng client-seitigen code. Ich bin der Planung über die Verwendung JWT für die Kommunikation zwischen client-Seite und server-Seite. Wenn ein Benutzer-logins mit Ihren oauth-cred, bekomme ich ein JSON-Objekt zurück, von dem Anbieter mit uid, name, login, access_token und andere details.
Ich habe Mühe mit der Auswahl einer Strategie zum Umgang mit Benutzer-Anmeldung. Es gibt keine Anmeldung, da es OAuth. Also die Strömung ist, wenn der Benutzer nicht in meiner db, erstellen Sie es. Ich nicht support-E-Mail/Passwort-Authentifizierung. Was wäre die fließen, wenn ein Benutzer meldet sich mit einem OAuth-provider für die erste Zeit? Sollte emberjs senden Sie alle details, die Sie im backend auf jedes Zeichen, so dass backend können neue Benutzer in der db?
Was sollte ein Teil meiner JWT Körper? Ich dachte, die uid und Anbieter geliefert access-token. Eine Frage, die ich denken kann ist hier, dass provider bestimmte access-token ändern können. Der Benutzer kann den Widerruf der token vom Anbieter der Website und meldet sich wieder mit emberjs.
Bin ich offen, schreiben die front-end-in jeder anderen javascript-client-side-framework, wenn es macht es leichter.
- Sind Sie nach einer Beschreibung, wie es zu tun oder den code? Beachten Sie, ember und Knoten sind vollkommen in Ordnung, die tech-stack für die client-und-backend-sollte auch hier kein wesentlicher Unterschied zu der Lösung.
- Ich bin auf der Suche für einen Ablauf auf, wie die verschiedenen Komponenten kommunizieren sollen, in welchem Stadium. Ich brauche keinen code
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn wir reden hier nicht nur arbeiten, sondern auch sicher, stateless-Authentifizierung, die Sie benötigen, zu prüfen, richtigen Strategie mit den beiden
access
undrefresh
Token.Access token ist ein token, welches einen Zugriff auf eine geschützte Ressource.
Expiration
hier installiert werden könnte-etwa in ~1 Stunde (kommt auf deine überlegungen).Refresh token ist ein spezielles token, die verwendet werden sollte, um auf diese Weise zusätzliche
access token
im Falle dass es abgelaufen war oder die Sitzung des Benutzers aktualisiert wurde. Natürlich müssen Sie machen es zu lange gelebt (im Vergleich mitaccess token
) und sichere so viel wie möglich.Expiration
hier installiert werden könnte-etwa in ~10 Tagen oder sogar mehr (hängt auch davon ab, in deine überlegungen).FYI: Seit
refresh tokens
sind lange lebte, um Sie, wirklich sicher ist möchten Sie vielleicht, um Sie zu speichern in die Datenbank (refresh token-Anfragen werden selten ausgeführt). Auf diese Weise, sagen wir mal, auch wenn Sie Ihre refresh-token wurde gehackt irgendwie und jemand regeneriertaccess/refresh
Token, natürlich, verlieren Sie die Berechtigungen, aber dann kann man noch am system anmelden, da Sie wissen login/pass (falls Sie Sie später verwenden) oder einfach nur, indem Sie sich über jedes soziale Netzwerk.Wo Sie speichern diese Token?
Grundsätzlich gibt es 2 gemeinsame Orte:
Gut zu gehen, aber in der gleichen Zeit riskant genug. Speicher ist zugänglich über javascript-code auf der gleichen domain. Das bedeutet, dass im Falle Sie haben XSS, Ihres Token könnten gehackt werden. So durch die Wahl dieser Methode müssen Sie aufpassen und Kodieren/escape, alle nicht vertrauenswürdigen Daten. Und selbst wenn Sie es Taten, ich bin mir ziemlich sicher, dass du einige Bündel von 3rd-party-client-side-Module und es gibt keine Garantie jeder von Ihnen hat einige bösartigen code.
Auch
Web Storage
erzwingt keine sicheren standards bei der übertragung. So müssen Sie sicher sein, JWT gesendet wird überHTTPS
und nieHTTP
.Mit bestimmten
HttpOnly
option cookies sind nicht zugänglich über javascript und sind immun gegen XSS. Sie können auch festlegen, dass dieSecure
cookie-flag zu garantieren, wird das cookie nur über HTTPS gesendet.Aber cookies sind anfällig für eine andere Art von Angriff: cross-site request forgery (CSRF).
In diesem Fall
CSRF
könnte verhindert werden, indem eine Art von synchronisierten token-Muster. Es ist eine gute Umsetzung inAngularJS
im Überlegungen Zur Sicherheit Abschnitt.Einer Artikel möchten Sie vielleicht zu Folgen.
Um zu illustrieren, wie es im Allgemeinen funktioniert:
Paar Worte über JWT selbst:
Deutlich zu machen, es ist wirklich cool JWT-Debugger von Auth0 Jungs.
Es werden 2 (manchmal 3) gemeinsame Ansprüche Typen:
public
,private
(und vorbehalten).Beispiel
JWT
body (payload können, was Sie wollen):Mehr Informationen über
JWT
Struktur finden Sie hier.Antwort auf die zwei konkreten Fragen, die Sie gestellt:
Wann immer ein Benutzer meldet sich an oder loggt sich über die oauth-und Ihr Kunde erhält eine neue access-token zurück, ich würde upsert (update oder insert), die es in Ihr Benutzer-Tabelle (oder eine Sammlung) zusammen mit allen neuen oder aktualisierten Informationen, die Sie abgefragt haben, über die Benutzer von dem oauth-provider-API. Ich schlage vor, speichern Sie es direkt auf jeder Benutzer-Datensatz zu gewährleisten, die access token und zugeordnete Profildaten-änderungen atomar. Im Allgemeinen würde ich in der Regel verfassen, diese in eine Art von middleware, führt automatisch die folgenden Schritte aus, wenn ein neues token vorhanden ist.
Den JWT Körper besteht im Allgemeinen aus den Nutzer Ansprüche. Ich persönlich sehe wenig nutzen für die Speicherung der provider access-token in den Körper eines JWT token, da hätte es einige Vorteile, um Ihre client-app (es sei denn, Sie werden tun eine Menge der direkten API-Aufrufe vom client an deren API, die ich lieber tun, ruft die server-Seite und senden Sie meine app-client wieder einen normalisierten Satz von Ansprüchen, die sich auf meine eigenen Schnittstelle). Durch das schreiben Ihrer eigenen Ansprüche-Schnittstelle, werden Sie nicht haben, zu arbeiten, um die verschiedenen Unterschiede vorhanden, die von mehreren Anbietern für Ihre client-app. Ein Beispiel HIERFÜR wäre Koaleszenz Twitter und Facebook spezifische Felder, die unterschiedlich benannt sind Ihre APIs, um gemeinsame Felder, die Sie speichern auf Ihrem Benutzer-Profil-Tabelle, dann die Einbettung von Ihrem lokalen Profil Felder, die als Forderungen in Ihre JWT Körper interpretiert werden, die durch Ihre client-app. Es ist ein zusätzlicher Vorteil für diese, dass Sie keine persistenten Daten, die austreten könnte, in die Zukunft, in eine unverschlüsselte JWT token.
Ob oder nicht Sie speichern die oauth-Anbieter geliefert access token innerhalb des JWT token Körper, werden Sie brauchen, um Erteilung einer neuen JWT token jedes mal die Profil Daten ändern (Sie können ein Mechanismus zur Umgehung Ausgabe neuer JWT Token, wenn kein Profil-updates aufgetreten ist und die vorherigen token ist immer noch gut).
Zusätzlich zu den gewünschten Profil-Felder speichern Sie als Forderungen im JWT token Körper, würde ich immer wieder definieren Sie die standard - JWT token-Körper-Felder von:
Für alle OAuth-workflow sollte man unbedingt die passportjs Bibliothek. Sollten Sie auch Lesen Sie die vollständige Dokumentation. Es ist leicht zu verstehen, aber ich machte den Fehler nicht Lesen die die ganze Sache das erste mal und kämpfte. Es enthält die OAuth-Authentifizierung mit über 300 Anbietern und Ausgabe von Token.
Dennoch, wenn Sie wollen, um es manuell tun, oder wollen Sie eine grundlegende Verständnis, hier ist die Strömung, die ich benutzen würde:
Frontend einen login-Seite mit einer Liste Sign-in mit Google/Facebook etc, wo OAuth implementiert ist.
Erfolgreiche OAuth-Ergebnisse in eine uid, login, access_token etc. (JSON-Objekt)
Buchen Sie die JSON-Objekt zu Ihrem
/login/
route in Ihrem Node.js -Anwendung. (Ja, Sie senden die gesamte Antwort unabhängig davon, ob Sie einen neuen oder vorhandenen Benutzer. Senden von zusätzlichen Daten ist hier besser als auf zwei Anfragen)Backend-Anwendung liest die
uid
und dieaccess_token
. Sicherstellen, dass dieaccess_token
gültig ist, indem Sie folgende (https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#checktoken) oder Fragen für den Benutzer die Daten von dem provider mit dem access-token. (Dieser Fehler für ungültige access-token, da die OAuth-access-Token generiert werden, auf einer pro-app/Entwickler-basis) suchen Sie Jetzt Ihren backend-DB.Wenn die
uid
in der Datenbank vorhanden ist, aktualisieren Sie die Benutzer access_token und expiresIn in der DB. (Die access_token können Sie weitere Informationen erhalten Sie von Facebook für diesen bestimmten Benutzer und es ermöglicht den Zugriff für ein paar Stunden in der Regel.)Anderen, erstellen Sie einen neuen Benutzer mit der uid, login etc-info.
Nach der Aktualisierung der access_token oder erstellen Sie einen neuen Benutzer, die Sie senden, JWT token mit der
uid
. (Kodierung der jwt mit einem Geheimnis, dies würde sicherstellen, dass es gesendet wurde, durch Sie und nicht manipuliert wurden. Kasse https://github.com/auth0/express-jwt)Auf dem frontend nach dem Benutzer empfangen hat, die von jwt
/login
, speichern Sie es aufsessionStorage
durchsessionStorage.setItem('jwt', token);
Auf dem frontend haben, fügen Sie auch die folgenden:
if ($window.sessionStorage.token) {
xhr.setRequestHeader("Authorization", $window.sessionStorage.token);
}
Dies würde sicherstellen, dass, wenn es ist ein jwt token, ist es geschickt, mit jeder Anfrage.
app.use(jwt({ secret: 'shhhhhhared-secret'}).unless({path: ['/login']}));
Dies würde bestätigen, dass jwt für alles in Ihrem Weg, sicherzustellen, dass der Benutzer angemeldet ist-in andernfalls nicht Zugriff zulassen und umleiten auf die login-Seite. Die Ausnahme hier ist
/login
da das ist, wo Sie geben beide Ihre neuen oder nicht authentifizierte Benutzer ein JWT.Finden Sie weitere Informationen auf der Github-URL auf, wie man den token und finden Sie heraus, welcher Benutzer die Anfrage Sie sind derzeit.
Access-Control-Allow-Origin: http://www.foo.com
auf Ihre back-End, so dass nurOrigin: http://www.foo.com
senden können POST-Daten an/login