Lass uns vom Anfang an diskutieren:
JWT ist ein sehr moderner, einfacher und sicherer Ansatz, der für Json Web Tokens steht. Json Web Tokens sind eine zustandslose Lösung für die Authentifizierung. Es ist also nicht erforderlich, irgendeinen Sitzungszustand auf dem Server zu speichern, was natürlich perfekt für restful APIs ist. Restful APIs sollten immer zustandslos sein, und das am weitesten verbreitete Alternativ zur Authentifizierung mit JWTs ist es, einfach den Login-Zustand des Benutzers auf dem Server mithilfe von Sitzungen zu speichern. Aber das folgt natürlich nicht dem Prinzip, dass restful APIs zustandslos sein sollten, und deshalb sind Lösungen wie JWT beliebt und effektiv geworden.
Lassen Sie uns nun herausfinden, wie die Authentifizierung tatsächlich mit Json Web Tokens funktioniert. Angenommen, wir haben bereits einen registrierten Benutzer in unserer Datenbank. Der Client des Benutzers beginnt, indem er einen POST-Antrag mit dem Benutzernamen und dem Passwort stellt. Die Anwendung überprüft dann, ob der Benutzer vorhanden ist und ob das Passwort korrekt ist, dann generiert die Anwendung einen eindeutigen Json Web Token nur für diesen Benutzer.
Der Token wird mithilfe eines geheimen Strings erstellt, der auf einem Server gespeichert ist. Als Nächstes sendet der Server diesen JWT an den Client, der ihn entweder in einem Cookie oder im lokalen Speicher speichert.
Auf diese Weise ist der Benutzer authentifiziert und im Grunde genommen in unsere Anwendung eingeloggt, ohne einen Zustand auf dem Server zu hinterlassen.
Der Server weiß also tatsächlich nicht, welcher Benutzer eingeloggt ist, aber natürlich weiß der Benutzer, dass er eingeloggt ist, weil er einen gültigen Json Web Token hat, der ein bisschen wie ein Reisepass ist, um auf geschützte Teile der Anwendung zuzugreifen.
Noch einmal, um sicherzugehen, dass Sie das Konzept verstanden haben. Ein Benutzer ist eingeloggt, sobald er seinen eindeutigen gültigen Json Web Token zurückbekommt, der nirgendwo auf dem Server gespeichert ist. Und deshalb ist dieser Prozess vollständig zustandslos.
Dann, jedes Mal wenn ein Benutzer auf eine geschützte Route zugreifen möchte, beispielsweise auf seine Benutzerprofil-Daten. Sendet er seinen Json Web Token zusammen mit einer Anfrage, es ist ein bisschen wie seinen Reisepass vorzuzeigen, um Zugang zu dieser Route zu erhalten.
Sobald die Anfrage den Server erreicht, wird unsere App dann überprüfen, ob der Json Web Token tatsächlich gültig ist und ob der Benutzer wirklich derjenige ist, für den er sich ausgibt. Nun werden die angeforderten Daten an den Client gesendet und wenn nicht, wird es einen Fehler geben, der dem Benutzer mitteilt, dass er nicht berechtigt ist, auf diese Ressource zuzugreifen.
All diese Kommunikation muss über https erfolgen, also über sicheres verschlüsseltes Http, um zu verhindern, dass jemand Zugriff auf Passwörter oder Json Web Tokens erhält. Nur dann haben wir ein wirklich sicheres System.
Ein Json Web Token sieht so aus wie der linke Teil dieses Screenshots, der aus dem JWT-Debugger auf jwt.io stammt. Im Wesentlichen, es ist ein Codierungsstring, der aus drei Teilen besteht. Der Header, die Nutzlast und die Signatur. Jetzt ist der Header einfach Metadaten über das Token selbst und die Nutzlast sind die Daten, die wir in das Token kodieren können, beliebige Daten, die wir möchten. Je mehr Daten wir hier kodieren wollen, desto größer wird das JWT. Wie auch immer, diese beiden Teile sind einfach Klartext, der kodiert, aber nicht verschlüsselt wird.
Daher kann jeder sie dekodieren und lesen, wir können hier keine sensiblen Daten speichern. Aber das ist überhaupt kein Problem, weil im dritten Teil, also in der Signatur, wird es wirklich interessant. Die Signatur wird mithilfe des Headers, der Nutzlast und des Geheimnisses erstellt, das auf dem Server gespeichert ist.
Und dieser gesamte Prozess wird dann signing the Json Web Token genannt. Der Signaturalgorithmus verwendet den Header, die Nutzlast und das Geheimnis, um eine eindeutige Signatur zu erstellen. Also nur diese Daten plus das Geheimnis können diese Signatur erstellen, verstanden? Dann, zusammen mit dem Header und der Nutzlast, bilden diese Signatur das JWT, das dann an den Client gesendet wird.
Wenn der Server ein JWT erhält, um Zugriff auf eine geschützte Route zu gewähren, muss er es überprüfen, um festzustellen, ob der Benutzer wirklich derjenige ist, für den er sich ausgibt. Mit anderen Worten, es wird überprüft, ob niemand die Daten im Header und in der Nutzlast des Tokens geändert hat. Also, dieser Verifizierungsschritt überprüft, ob keine dritte Partei tatsächlich entweder den Header oder die Nutzlast des Json Web Tokens geändert hat.
Also, wie funktioniert diese Verifizierung tatsächlich? Nun, es ist eigentlich ziemlich einfach. Sobald das JWT empfangen wurde, wird die Verifizierung den Header und die Nutzlast nehmen und zusammen mit dem immer noch auf dem Server gespeicherten Geheimnis im Grunde einen Test-Signatur erstellen.
Aber die ursprüngliche Signatur, die generiert wurde, als das JWT zum ersten Mal erstellt wurde, ist immer noch im Token enthalten, richtig? Und das ist der Schlüssel zu dieser Verifizierung. Denn jetzt müssen wir nur noch die Test-Signatur mit der ursprünglichen Signatur vergleichen. Und wenn die Test-Signatur mit der ursprünglichen Signatur übereinstimmt, dann bedeutet das, dass die Nutzlast und der Header nicht geändert wurden.
Denn wenn sie geändert worden wären, dann müsste die Test-Signatur anders sein. Daher, in dem Fall, dass keine Daten verändert wurden, können wir dann den Benutzer authentifizieren. Und natürlich, wenn die beiden Signaturen tatsächlich unterschiedlich sind, nun, dann bedeutet das, dass jemand die Daten manipuliert hat. Normalerweise indem sie versuchen, die Nutzlast zu ändern. Aber diese dritte Partei, die die Nutzlast manipuliert, hat natürlich keinen Zugriff auf das Geheimnis, also können sie das JWT nicht signieren. Deshalb wird die ursprüngliche Signatur niemals mit den manipulierten Daten übereinstimmen. Und deshalb wird die Verifizierung in diesem Fall immer scheitern. Und das ist der Schlüssel, der das gesamte System funktionieren lässt. Das ist die Magie, die JWT so einfach, aber auch extrem leistungsstark macht.