Was ist JWT? Dieser Artikel wird Ihnen helfen, JWT zu verstehen, die Anwendung von JWT im Knoten vorzustellen und die Vor- und Nachteile von JWT zu erläutern. Ich hoffe, dass er für alle hilfreich ist!
JWT ist die Abkürzung für JSON Web Token , eine Authentifizierungslösung in der Netzwerkanwendungsumgebung. Beim herkömmlichen Authentifizierungsmechanismus handelt es sich lediglich um die folgenden Schritte:
1. Der Benutzer sendet das Kontopasswort an den Server. 2. Nachdem der Server das Kontokennwort überprüft hat, speichert er einige benutzerbezogene Informationen, Benutzerrollen oder Ablaufzeit usw. in der aktuellen Sitzung. 3. Der Server gibt dem Benutzer eine Sitzungs-ID und schreibt sie in das Cookie des Benutzers oder der Client speichert sie lokal. 4. Jedes Mal, wenn der Benutzer einen Dienst anfordert, muss er diese Sitzungs-ID mitbringen, möglicherweise über Cookies oder andere Methoden. 5. Nachdem der Server es empfangen hat, kehrt er zur Datenbank zurück, um die aktuelle Sitzungs-ID abzufragen und zu überprüfen, ob der Benutzer über die Berechtigung verfügt.
Ein Vorteil dieses Modells besteht darin, dass der Server die Berechtigungen des Benutzers jederzeit beenden und auf die Datenbank zugreifen kann, um die Sitzungsinformationen des aktuellen Benutzers zu ändern oder zu löschen. Es gibt jedoch auch einen Nachteil: Wenn es sich um einen Servercluster handelt, müssen alle Computer die Sitzungsinformationen gemeinsam nutzen, um sicherzustellen, dass jeder Server dieselben Sitzungsspeicherinformationen erhalten kann. Obwohl diese Probleme gelöst werden können, ist der Arbeitsaufwand enorm.
Der Vorteil der JWT-Lösung besteht darin, dass diese Informationen nicht auf dem Client gespeichert werden. Jedes Mal, wenn eine Anfrage angenommen wird, muss sie nur überprüft werden.
Lassen Sie uns kurz über das Prinzip von JWT sprechen. Wenn der Client eine Authentifizierungsanforderung sendet, generiert der Server nach der Authentifizierung des Benutzers ein JSON-Objekt, das wahrscheinlich Informationen wie „Wer sind Sie, was machen Sie“ usw. enthält ., Ablaufzeit ", wichtig ist, dass es eine Ablaufzeit geben muss; das allgemeine Format ist:
{ Benutzername: „thief string äh“, Rolle: „World Code Farmer“, Endzeit: „20. Mai 2022“ }
Es wird jedoch nicht auf so oberflächliche Weise an Sie weitergegeben. Es wird über einen umkehrbaren Signaturalgorithmus basierend auf dem angegebenen Signaturalgorithmus und einigen Informationen über die von Ihnen übermittelte Nutzlast signiert und übertragen :
Wie aus dem Bild hervorgeht, sind die zurückgegebenen Informationen grob in drei Teile unterteilt. Die linke Seite ist das Ergebnis, das an den Client zurückgegeben wird. Die rechte Seite ist auch der dekodierte Quellcode durch „Punkte“ getrennt. Es besteht eine Eins-zu-eins-Entsprechung zwischen den drei Farben Rot, Lila und Cyan:
Der erste rote Teil ist der Header. Der Signaturalgorithmus im Bild ( Standard HS256 ) ist ein symmetrischer Algorithmus, der zwischen den beiden Parteien geteilt wird Feldbezeichner ist vom Typ JWT;
Der zweite violette Teil, Payload, ist ein JSON-Objekt, bei dem es sich um die eigentlichen zu übertragenden Daten handelt. Es gibt sieben offizielle Felder, die verwendet werden können:
iss (Emittent): Emittent
exp (Ablaufzeit): Ablaufzeit
sub (Betreff): Betreff
aud (Publikum): Publikum
nbf (Nicht vorher): Effektive Zeit
iat (Issued At): Ausstellungszeitpunkt
jti (JWT-ID): Nummer
Zusätzlich zu diesen Feldern können Sie auch einige benutzerdefinierte Felder erstellen. Da JWT standardmäßig nicht verschlüsselt ist, sollten Sie bei der Verwendung darauf achten, keine sensiblen Daten zu verwenden.
Der dritte Teil ist die Signature
. Bei diesem Teil handelt es sich um einen geheimen Schlüssel, der von Ihnen angegeben wird und nur auf dem Server vorhanden ist. Anschließend wird der im Header angegebene Algorithmus zum Signieren mithilfe der folgenden Signaturmethode verwendet.
Lassen Sie uns die spezifische Verwendung unten erleben:
Schritt 1: Wir müssen ein Nodejs-Projekt erstellen; ein Projekt über npm init -y
initialisieren; dann müssen wir Abhängigkeiten installieren, einschließlich express
, jsonwebtoken
und nodemon
:
$ npm i express jsonwebtoken nodemon
Fügen Sie dann den Befehl nodemon app.js
im Feld scripts
in package.json
hinzu:
"Skripte": { „start“: „nodemon app.js“ },
Schritt 2: Initialisieren Sie die Knotenanwendung und erstellen Sie die Datei app.js im Stammverzeichnis.
// app.js const express = require("express"); const app = express(); app.use(express.json()); app.listen(3000, () => { console.log(3000 + "listening..."); // Port 3000 abhören});
Schritt 3: Führen Sie jsonwebtoken
ein und erstellen Sie den privaten Schlüssel der Schnittstelle und des Servers.
// app.js //...... const jwt = require("jsonwebtoken"); const jwtKey = "~!@#$%^&*()+,"; // ...
jwtKey
hier ist unser benutzerdefinierter privater Schlüssel, der nur auf dem Server gespeichert wird. Danach haben wir begonnen, eine /login-Schnittstelle zum Anmelden zu schreiben, eine lokale Simulationsdatenbank zur Überprüfung zu erstellen und diese über die Methode jwt.sign
durchzuführen. Signatur überprüfen:
// app.js const Datenbank = { Benutzername: „Benutzername“, Passwort: „Passwort“, }; app.post("/login", (req, res) => { const { Benutzername, Passwort } = req.body; if (Benutzername === Datenbank.Benutzername && Passwort === Datenbank.Passwort) { jwt.sign( { Benutzername, }, jwtKey, { läuft ab: „30S“, }, (_, Token) => { res.json({ Benutzername, Meldung: „Anmeldung erfolgreich“, Token, }); } ); } });
Im obigen Code haben wir database
Datenbankvariable erstellt, um die Erstellung einer lokalen Konto- und Passwortdatenbank zur Überprüfung der Anmeldung zu simulieren. Anschließend haben wir eine /login
post
eingerichtet. Nachdem wir überprüft haben, dass das Konto und das Passwort vollständig übereinstimmen, haben wir sie über jsonwebtoken
importiert Verwenden Sie zum Signieren die sign
-Methode unter dem jwt
Objekt. Diese Methode verfügt über drei Schnittstellensignaturen:
Exportfunktionszeichen( Nutzlast: string |. Buffer |. SecretOrPrivateKey: Geheimnis, Optionen?: SignOptions, ): string; Exportfunktionszeichen( Nutzlast: string |. Buffer |. SecretOrPrivateKey: Geheimnis, Rückruf: SignCallback, ): Leere; Exportfunktionszeichen( Nutzlast: string |. Buffer |. SecretOrPrivateKey: Geheimnis, Optionen: SignOptions, Rückruf: SignCallback, ): Leere;
Die Methode der Funktionsüberladung wird hier verwendet, um die letzte Schnittstellensignatur zu implementieren. Der erste object
kann ein benutzerdefinierter Objekttyp, ein Buffer
oder direkt ein string
sein und passt einige Felder an, da JWT diese Daten beim Signieren auch signiert. Beachten Sie jedoch, dass Sie hier keine vertraulichen Daten verwenden sollten, da JWT standardmäßig nicht verschlüsselt ist wurde nicht manipuliert und der Prozess der Überprüfung der Signatur wird als Verifizierung bezeichnet.
Natürlich können Sie den Original-Token auch verschlüsseln und dann übertragen;
Der zweite Parameter ist der geheime Schlüssel, den wir zum Signieren auf dem Server speichern. Normalerweise verwendet JWS den von JWA bereitgestellten HS256-Algorithmus plus einen Schlüssel. Möglicherweise müssen mehrere Dienste JWT überprüfen. Wenn der Schlüssel in jedem Dienst gespeichert wird, wird die Sicherheit erheblich verringert. Sie müssen wissen, dass jeder JWT nach Belieben fälschen kann.
Der dritte Parameter: ist die Signaturoption SignOptions
, die Signatur der Schnittstelle:
Exportschnittstelle SignOptions { Algorithmus?: Algorithmus |. undefiniert; Schlüssel-ID?: string |. undefiniert; läuft ab?: string |. Zahl |. /** ausgedrückt in Sekunden oder einer Zeichenfolge, die eine Zeitspanne beschreibt [zeit/ms](https://github.com/zeit/ms.js), z. B.: 60, „2 Tage“, „10 Stunden“, „7 Tage“. */ notBefore?: string |. number |. Publikum?: string |. string[] |. Betreff?: string |. undefiniert; Emittent?: string |. undefiniert; jwtid?: string |. mutatePayload?: boolean |. noTimestamp?: boolean |. Header?: JwtHeader |. Kodierung?: string |. undefiniert; }
Hier verwenden wir das Feld expiresIn
, um die Alterungszeit anzugeben. Informationen zu den Verwendungsmethoden finden Sie in diesem Dokument.
Der vierte Parameter ist ein Rückruf. Der zweite Parameter des Rückrufs ist token
wir durch die Signatur generiert haben. Dieses token
wird schließlich an das Frontend zurückgegeben, damit es lokal auf dem Frontend gespeichert und zur Überprüfung an den Server übertragen werden kann auf jede Anfrage.
Als nächstes überprüfen wir diese Schnittstelle: Ich habe das REST-Client- Plug-in in vscode installiert, dann eine request.http
Datei im Stammverzeichnis erstellt und die angeforderten Informationen in die Datei geschrieben:
POST http://localhost:3000/login Inhaltstyp: application/json { „Benutzername“: „Benutzername“, „Passwort“: „Passwort“ }
Führen Sie dann den Befehl npm run start
in der Befehlszeile aus, um den Dienst zu starten, und klicken Sie dann über der Datei requset.http
auf die Schaltfläche Send Request
um die Anfrage zu senden:
Nachdem die Anfrage erfolgreich war, wird eine Antwortnachricht wie diese angezeigt:
Das token
Feld ist token
;
Lassen Sie uns überprüfen, ob dieses token
gültig ist. Wir schreiben nach der Anmeldung eine Schnittstelle:
app.get("/afterlogin", (req, res) => { const { Header } = req; const token = headers["authorization"].split(" ")[1]; //Token in das Autorisierungsfeld des Headers einfügen jwt.verify(token, jwtKey, (err, payload) => { if (err) return res.sendStatus(403); res.json({ message: „Authentifizierung erfolgreich“, Nutzlast }); }); });
In diesem Code wird token
durch Abrufen token
im authorization
im Anforderungsheader abgerufen. Überprüfen Sie dann, ob das token
gültig ist, indem Sie jwt.verify
aufrufen. Diese Methode verfügt über drei Parameter:
// Es gibt vier Schnittstellensignaturen. Sie können die Dokumentation selbst überprüfen. Exportfunktion überprüfen( Token: Zeichenfolge, //Token, das überprüft werden muss SecretOrPublicKey: Secret |. GetPublicKeyOrSecret, // Der im Server-Callback definierte Signaturschlüssel?: VerifyCallback<JwtPayload string>, // Rückruf, um das Ergebnis der Überprüfungsinformationen zu erhalten): void;
Als nächstes kopieren wir token
auf das wir gerade geantwortet haben, in den Anforderungsheader:
### GET http://localhost:3000/afterlogin Autorisierung: Inhaber eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXJuYW1lIiwiaWF0IjoxNjUyNzg5NzA3LCJleHAiOjE2NTI3ODk3Mzd9.s9fk3YLhxTUcpUgCfIK4xQ. N58 Hk_XEP5y9GM9A8jBbY
Die bisherige Bearer-Authentifizierung ist die Standardauthentifizierungsmethode im http-Protokoll.
Klicken Sie außerdem auf Send Request
. Wenn Sie die Antwort im Bild unten sehen, bedeutet dies, dass die Antwort erfolgreich war:
Tatsächlich sind dies einige einfache Anwendungen von JWT. Lassen Sie uns als Nächstes über die Vor- und Nachteile von JWT selbst sprechen.
Der von JWT belegte Speicherplatz ist tatsächlich nicht gering. Wenn wir zu viele Informationen signieren müssen, überschreitet das Token wahrscheinlich die Längenbeschränkung des Cookies. Vergleichen Sie beispielsweise diese beiden Bilder:
Mit zunehmender Informationsmenge in der Nutzlast nimmt natürlich auch die Länge des Tokens zu.
Sicherheit: Wenn token
zu viel Platz einnimmt, beträgt der maximale Speicherplatz Cookie
nur 4 KB. Das Front-End kann im lokalen Speicher wie localStorage
gespeichert werden, verursacht jedoch ein Problem, wenn es nicht platziert wird Im Cookie wird die Sicherheit erheblich verringert. Es besteht die Gefahr, dass es über das JS-Skript abgerufen wird, was bedeutet, dass jeder Hacker alles damit machen kann.
Unflexible Aktualität besteht tatsächlich darin, dass das Benutzer- token
nicht dauerhaft gespeichert werden muss. Wie Sie gerade gesehen haben, enthält token
Signatur auch die Ablaufzeit Wird die Ablaufzeit geändert, wird token
manipuliert. Da es keine Möglichkeit gibt, das Ablaufdatum zu speichern und manuell zu ändern, ist es schwierig, das token
sofort zu löschen. Wenn sich der Benutzer zweimal anmeldet und dann zwei token
generiert werden Grundsätzlich werden zwei token
generiert, die alle gültig sind.
Im Obigen geht es hauptsächlich um einige Punkte:
Das Prinzip von JWT besteht hauptsächlich darin, den privaten Schlüssel des Servers für die Kommunikation mit token
zu verwenden.
Außerdem wird die Zusammensetzung der internen Daten von JWT vorgestellt, die von Header verwendet werden, um den Signaturalgorithmus und -typ anzugeben, Nutzlast zum Übertragen von JSON-Daten und Signature, um den Signaturalgorithmus für die Daten auszuführen und Manipulationen zu verhindern.
Es wird eine detaillierte Einführung in die Verwendung von JWT über NodeJS, die Datensignatur über die sign
-Methode und die Signaturüberprüfung über die verify
-Methode gegeben.
Es werden auch einige Nachteile von JWT eingeführt:
Zum einen steigt der Speicherplatz mit zunehmender Menge an Signaturdaten.
Wenn der Speicherplatz zu groß ist, wird er nicht in Cookie
mit einer relativ hohen Sicherheitsstufe gespeichert, sodass das Skript nach Belieben abgerufen werden kann.
Dann gibt es noch die Aktualität, die die Aktualität von token
nicht flexibel steuern kann;
Dies ist der Demo-Quellcode von nodejs oben als Referenz.