Bauen | Abhängigkeit |
---|---|
Eine Implementierung von JSON-Web-Tokens.
Dies wurde gegen draft-ietf-oauth-json-web-token-08
entwickelt. Es nutzt Node-JWS
$ npm jsonwebtoken installieren
Von v8 bis v9
Von v7 bis v8
(Asynchron) Wenn ein Rückruf bereitgestellt wird, wird der Rückruf mit dem err
oder dem JWT aufgerufen.
(Synchron) Gibt das JsonWebToken als Zeichenfolge zurück
payload
kann ein Objektliteral, ein Puffer oder eine Zeichenfolge sein, die gültiges JSON darstellt.
Bitte beachten Sie , dass
exp
oder andere Ansprüche nur gesetzt werden, wenn die Nutzlast ein Objektliteral ist. Puffer- oder String-Payloads werden nicht auf JSON-Gültigkeit überprüft.
Wenn es sich
payload
nicht um einen Puffer oder eine Zeichenfolge handelt, wird sie mithilfe vonJSON.stringify
in eine Zeichenfolge umgewandelt.
secretOrPrivateKey
ist eine Zeichenfolge (UTF-8-codiert), ein Puffer, ein Objekt oder ein KeyObject, das entweder das Geheimnis für HMAC-Algorithmen oder den PEM-codierten privaten Schlüssel für RSA und ECDSA enthält. Im Falle eines privaten Schlüssels mit Passphrase kann ein Objekt { key, passphrase }
verwendet werden (basierend auf der Kryptodokumentation). Stellen Sie in diesem Fall sicher, dass Sie die Option algorithm
übergeben. Beim Signieren mit RSA-Algorithmen beträgt die minimale Modullänge 2048, außer wenn die Option „allowInsecureKeySizes“ auf „true“ gesetzt ist. Private Schlüssel unterhalb dieser Größe werden mit einem Fehler abgelehnt.
options
:
algorithm
(Standard: HS256
)
expiresIn
: ausgedrückt in Sekunden oder eine Zeichenfolge, die eine Zeitspanne in Vercel/ms beschreibt.
Beispiel:
60
,"2 days"
,"10h"
,"7d"
. Ein numerischer Wert wird als Sekundenanzahl interpretiert. Wenn Sie eine Zeichenfolge verwenden, stellen Sie sicher, dass Sie die Zeiteinheiten (Tage, Stunden usw.) angeben. Andernfalls wird standardmäßig die Einheit Millisekunden verwendet ("120"
entspricht"120ms"
).
notBefore
: ausgedrückt in Sekunden oder eine Zeichenfolge, die eine Zeitspanne in Vercel/ms beschreibt.
Beispiel:
60
,"2 days"
,"10h"
,"7d"
. Ein numerischer Wert wird als Sekundenanzahl interpretiert. Wenn Sie eine Zeichenfolge verwenden, stellen Sie sicher, dass Sie die Zeiteinheiten (Tage, Stunden usw.) angeben. Andernfalls wird standardmäßig die Einheit Millisekunden verwendet ("120"
entspricht"120ms"
).
audience
issuer
jwtid
subject
noTimestamp
header
keyid
mutatePayload
: Wenn true, ändert die Vorzeichenfunktion das Nutzlastobjekt direkt. Dies ist nützlich, wenn Sie einen Rohverweis auf die Nutzlast benötigen, nachdem Ansprüche darauf angewendet wurden, diese aber noch nicht in ein Token kodiert wurde.
allowInsecureKeySizes
: Wenn true, können private Schlüssel mit einem Modulus unter 2048 für RSA verwendet werden
allowInvalidAsymmetricKeyTypes
: Wenn true, werden asymmetrische Schlüssel zugelassen, die nicht mit dem angegebenen Algorithmus übereinstimmen. Diese Option dient nur der Abwärtskompatibilität und sollte vermieden werden.
Es gibt keine Standardwerte für
expiresIn
,notBefore
,audience
,subject
undissuer
. Diese Ansprüche können auch direkt in der Nutzlast mitexp
,nbf
,aud
,sub
bzw.iss
bereitgestellt werden, Sie können sie jedoch nicht an beiden Stellen einschließen.
Denken Sie daran, dass exp
, nbf
und iat
NumericDate sind, siehe zugehöriger Token-Ablauf (exp-Anspruch)
Der Header kann über das options.header
-Objekt angepasst werden.
Generierte JWTs enthalten standardmäßig einen iat
-Anspruch (issued at), es sei denn, noTimestamp
ist angegeben. Wenn iat
in die Nutzlast eingefügt wird, wird es anstelle des echten Zeitstempels für die Berechnung anderer Dinge wie exp
verwendet, wenn in options.expiresIn
eine Zeitspanne angegeben ist.
Synchrones Vorzeichen mit Standard (HMAC SHA256)
var jwt = require('jsonwebtoken');var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
Synchrones Signieren mit RSA SHA256
// signieren mit RSA SHA256var privateKey = fs.readFileSync('private.key');var token = jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' });
Asynchron signieren
jwt.sign({ foo: 'bar' }, privateKey, { algorithm: 'RS256' }, function(err, token) { console.log(token);});
Einen JWT 30 Sekunden zurückdatieren
var old_token = jwt.sign({ foo: 'bar', iat: Math.floor(Date.now() / 1000) - 30 }, 'shhhhh');
Der Standard für JWT definiert einen exp
Anspruch für den Ablauf. Der Ablauf wird als NumericDate dargestellt:
Ein numerischer JSON-Wert, der die Anzahl der Sekunden vom 1970-01-01T00:00:00Z UTC bis zum angegebenen UTC-Datum/Uhrzeit darstellt, wobei Schaltsekunden ignoriert werden. Dies entspricht der IEEE Std 1003.1, 2013 Edition [POSIX.1]-Definition „Sekunden seit der Epoche“, in der jeder Tag genau 86400 Sekunden umfasst, abgesehen davon, dass nicht ganzzahlige Werte dargestellt werden können. Einzelheiten zu Datum/Uhrzeit im Allgemeinen und UTC im Besonderen finden Sie in RFC 3339 [RFC3339].
Das bedeutet, dass das exp
Feld die Anzahl der Sekunden seit der Epoche enthalten sollte.
Signieren eines Tokens mit einer Ablaufdauer von 1 Stunde:
jwt.sign({ exp: Math.floor(Date.now() / 1000) + (60 * 60), Daten: 'foobar'}, 'geheim');
Eine andere Möglichkeit, mit dieser Bibliothek ein solches Token zu generieren, ist:
jwt.sign({ data: 'foobar'}, 'secret', { expiresIn: 60 * 60 });//oder noch besser:jwt.sign({ Daten: 'foobar'}, 'geheim', { expiresIn: '1h' });
(Asynchron) Wenn ein Rückruf bereitgestellt wird, agiert die Funktion asynchron. Der Rückruf wird mit der dekodierten Nutzlast aufgerufen, wenn die Signatur gültig ist und optionaler Ablauf, Zielgruppe oder Aussteller gültig sind. Wenn nicht, wird es mit dem Fehler aufgerufen.
(Synchron) Wenn kein Rückruf bereitgestellt wird, agiert die Funktion synchron. Gibt die entschlüsselte Nutzlast zurück, wenn die Signatur gültig ist und optionaler Ablauf, Zielgruppe oder Aussteller gültig sind. Wenn nicht, wird der Fehler ausgegeben.
Warnung: Wenn das Token von einer nicht vertrauenswürdigen Quelle stammt (z. B. Benutzereingaben oder externe Anfragen), sollte die zurückgegebene dekodierte Nutzlast wie jede andere Benutzereingabe behandelt werden; Bitte stellen Sie sicher, dass Sie desinfizieren und nur mit erwarteten Eigenschaften arbeiten
token
ist die JsonWebToken-Zeichenfolge
secretOrPublicKey
ist eine Zeichenfolge (UTF-8-codiert), ein Puffer oder ein KeyObject, das entweder das Geheimnis für HMAC-Algorithmen oder den PEM-codierten öffentlichen Schlüssel für RSA und ECDSA enthält. Wenn jwt.verify
asynchron aufgerufen wird, kann secretOrPublicKey
eine Funktion sein, die den geheimen oder öffentlichen Schlüssel abrufen soll. Unten finden Sie ein detailliertes Beispiel
Wie in diesem Kommentar erwähnt, gibt es andere Bibliotheken, die Base64-codierte Geheimnisse erwarten (zufällige Bytes, die mit Base64 codiert werden). In diesem Fall können Sie Buffer.from(secret, 'base64')
übergeben. Dadurch wird das Geheimnis decodiert Bei Verwendung von Base64 und der Token-Überprüfung werden die ursprünglichen Zufallsbytes verwendet.
options
algorithms
: Liste von Strings mit den Namen der erlaubten Algorithmen. Zum Beispiel ["HS256", "HS384"]
.
Wenn nichts angegeben wird, werden Standardwerte basierend auf dem Typ des bereitgestellten Schlüssels verwendet
Geheimnis - ['HS256', 'HS384', 'HS512']
rsa – ['RS256', 'RS384', 'RS512']
ec - ['ES256', 'ES384', 'ES512']
Standard - ['RS256', 'RS384', 'RS512']
audience
: Wenn Sie die Zielgruppe ( aud
) überprüfen möchten, geben Sie hier einen Wert ein. Die Zielgruppe kann anhand einer Zeichenfolge, eines regulären Ausdrucks oder einer Liste von Zeichenfolgen und/oder regulären Ausdrücken überprüft werden.
Beispiel:
"urn:foo"
,/urn:f[o]{2}/
,[/urn:f[o]{2}/, "urn:bar"]
complete
: Gibt ein Objekt mit der dekodierten { payload, header, signature }
zurück, statt nur dem üblichen Inhalt der Nutzlast.
issuer
(optional): String oder Array von Strings mit gültigen Werten für das iss
-Feld.
jwtid
(optional): Wenn Sie die JWT-ID ( jti
) überprüfen möchten, geben Sie hier einen Zeichenfolgenwert an.
ignoreExpiration
: Wenn true
wird der Ablauf des Tokens nicht validiert.
ignoreNotBefore
...
subject
: Wenn Sie den Betreff ( sub
) überprüfen möchten, geben Sie hier einen Wert ein
clockTolerance
: Anzahl der Sekunden, die bei der Überprüfung der nbf
und exp
Ansprüche toleriert werden, um kleine Taktunterschiede zwischen verschiedenen Servern auszugleichen
maxAge
: das maximal zulässige Alter, damit Token noch gültig sind. Sie wird in Sekunden ausgedrückt oder ist eine Zeichenfolge, die eine Zeitspanne in Vercel/ms beschreibt.
Beispiel:
1000
,"2 days"
,"10h"
,"7d"
. Ein numerischer Wert wird als Sekundenanzahl interpretiert. Wenn Sie eine Zeichenfolge verwenden, stellen Sie sicher, dass Sie die Zeiteinheiten (Tage, Stunden usw.) angeben. Andernfalls wird standardmäßig die Einheit Millisekunden verwendet ("120"
entspricht"120ms"
).
clockTimestamp
: die Zeit in Sekunden, die als aktuelle Zeit für alle notwendigen Vergleiche verwendet werden soll.
nonce
: Wenn Sie nonce
-Anspruch überprüfen möchten, geben Sie hier einen Zeichenfolgenwert ein. Es wird bei Open ID für die ID-Tokens verwendet. (Open ID-Implementierungshinweise)
allowInvalidAsymmetricKeyTypes
: Wenn true, werden asymmetrische Schlüssel zugelassen, die nicht mit dem angegebenen Algorithmus übereinstimmen. Diese Option dient nur der Abwärtskompatibilität und sollte vermieden werden.
// ein Token überprüfen symmetric - synchronousvar decoded = jwt.verify(token, 'shhhhh');console.log(decoded.foo) // bar// ein Token überprüfen symmetricjwt.verify(token, 'shhhhh', function(err , entschlüsselt) { console.log(decoded.foo) // bar});// ungültiges Token - synchronoustry { var decoded = jwt.verify(token, 'wrong-secret');} Catch(err) { // err}// invalid tokenjwt.verify(token, 'wrong-secret', function(err, decoded) { // irrtümlich // undefiniert dekodiert});// ein Token überprüfen asymmetricvar cert = fs.readFileSync('public.pem'); // öffentlichen Schlüssel abrufenjwt.verify(token, cert, function(err, decoded) { console.log(decoded.foo) // bar});// verifiziere Audiencevar cert = fs.readFileSync('public.pem'); // öffentlichen Schlüssel abrufenjwt.verify(token, cert, { Audience: 'urn:foo' }, function(err, decoded) { // wenn die Zielgruppe nicht übereinstimmt, err == ungültige Zielgruppe});// Issuer überprüfenvar cert = fs.readFileSync('public.pem'); // öffentlichen Schlüssel abrufenjwt.verify(token, cert, { Audience: 'urn:foo', Issuer: 'urn:issuer' }, function(err, decoded) { // wenn der Aussteller nicht übereinstimmt, err == ungültiger Aussteller});// JWT-ID überprüfen cert = fs.readFileSync('public.pem'); // öffentlichen Schlüssel abrufenjwt.verify(token, cert, { Audience: 'urn:foo', Issuer: 'urn:issuer', jwtid: 'jwtid' }, function(err, decoded) { // wenn die JWT-ID nicht übereinstimmt, err == ungültige JWT-ID});// subjectvar überprüfen cert = fs.readFileSync('public.pem'); // öffentlichen Schlüssel abrufenjwt.verify(token, cert, { Audience: 'urn:foo', Issuer: 'urn:issuer', jwtid: 'jwtid', subject: 'subject' }, function(err, decoded) { // wenn Betreff nicht übereinstimmt, err == ungültiger Betreff});// alg mismatchvar cert = fs.readFileSync('public.pem'); // öffentlichen Schlüssel abrufenjwt.verify(token, cert, { algorithms: ['RS256'] }, function (err, payload) { // wenn token alg != RS256, err == ungültige Signatur});// Überprüfung mit getKey-Rückruf// Beispiel verwendet https://github.com/auth0/node-jwks-rsa als Möglichkeit, die Schlüssel abzurufen. var jwksClient = require('jwks-rsa');var client = jwksClient({ jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json'});function getKey(header, callback){ client.getSigningKey(header.kid, function(err, key) {var signingKey = key.publicKey || key.rsaPublicKey;callback(null, signingKey); });}jwt.verify(token, getKey, options, function(err, decoded) { console.log(decoded.foo) // bar});
(Synchron) Gibt die dekodierte Nutzlast zurück, ohne zu überprüfen, ob die Signatur gültig ist.
Warnung: Dadurch wird nicht überprüft, ob die Signatur gültig ist. Sie sollten dies nicht für nicht vertrauenswürdige Nachrichten verwenden. Sie möchten höchstwahrscheinlich stattdessen
jwt.verify
verwenden.
Warnung: Wenn das Token von einer nicht vertrauenswürdigen Quelle stammt (z. B. Benutzereingabe oder externe Anfrage), sollte die zurückgegebene dekodierte Nutzlast wie jede andere Benutzereingabe behandelt werden; Bitte stellen Sie sicher, dass Sie desinfizieren und nur mit erwarteten Eigenschaften arbeiten
token
ist die JsonWebToken-Zeichenfolge
options
:
json
: JSON.parse für die Nutzlast erzwingen, auch wenn der Header nicht "typ":"JWT"
enthält.
complete
: Gibt ein Objekt mit der dekodierten Nutzlast und dem Header zurück.
Beispiel
// Holen Sie sich die dekodierte Nutzlast und ignorieren Sie die Signatur, kein SecretOrPrivateKey erforderlich. var decoded = jwt.decode(token);// Holen Sie sich die dekodierte Nutzlast und den Header. header);console.log(decoded.payload)
Mögliche Fehler während der Überprüfung. Fehler ist das erste Argument des Verifizierungsrückrufs.
Es wird ein Fehler ausgegeben, wenn das Token abgelaufen ist.
Fehlerobjekt:
Name: 'TokenExpiredError'
Nachricht: „jwt abgelaufen“
abgelaufen am: [Ablaufdatum]
jwt.verify(token, 'shhhhh', function(err, decoded) { if (err) {/* err = { name: 'TokenExpiredError', message: 'jwt Expired', ExpiredAt: 1408621000 } */ }});
Fehlerobjekt:
Name: 'JsonWebTokenError'
Nachricht:
„Ungültiges Token“ – der Header oder die Nutzlast konnte nicht analysiert werden
„jwt malformed“ – das Token besteht nicht aus drei Komponenten (getrennt durch ein .
)
„JWT-Signatur ist erforderlich“
'ungültige Signatur'
'JWT-Zielgruppe ungültig. erwartet: [OPTIONS PUBLIKUM]'
'JWT-Aussteller ungültig. erwartet: [OPTIONS ISSUER]'
'JWT-ID ungültig. erwartet: [OPTIONS JWT ID]'
'JWT-Betreff ungültig. erwartet: [OPTIONS SUBJECT]'
jwt.verify(token, 'shhhhh', function(err, decoded) { if (err) {/* err = { name: 'JsonWebTokenError', message: 'jwt malformed' } */ }});
Wird ausgelöst, wenn die aktuelle Zeit vor dem NBF-Anspruch liegt.
Fehlerobjekt:
Name: 'NotBeforeError'
Meldung: „JWT nicht aktiv“
Datum: 2018-10-04T16:10:44.000Z
jwt.verify(token, 'shhhhh', function(err, decoded) { if (err) {/* err = { name: 'NotBeforeError', message: 'jwt not active', date: 2018-10-04T16:10:44.000Z } */ }});
Array unterstützter Algorithmen. Die folgenden Algorithmen werden derzeit unterstützt.
alg-Parameterwert | Digitale Signatur oder MAC-Algorithmus |
---|---|
HS256 | HMAC mit SHA-256-Hash-Algorithmus |
HS384 | HMAC mit SHA-384-Hash-Algorithmus |
HS512 | HMAC mit SHA-512-Hash-Algorithmus |
RS256 | RSASSA-PKCS1-v1_5 mit SHA-256-Hash-Algorithmus |
RS384 | RSASSA-PKCS1-v1_5 mit SHA-384-Hash-Algorithmus |
RS512 | RSASSA-PKCS1-v1_5 mit SHA-512-Hash-Algorithmus |
PS256 | RSASSA-PSS mit SHA-256-Hash-Algorithmus (nur Knoten ^6.12.0 ODER >=8.0.0) |
PS384 | RSASSA-PSS mit SHA-384-Hash-Algorithmus (nur Knoten ^6.12.0 ODER >=8.0.0) |
PS512 | RSASSA-PSS mit SHA-512-Hash-Algorithmus (nur Knoten ^6.12.0 ODER >=8.0.0) |
ES256 | ECDSA verwendet P-256-Kurve und SHA-256-Hash-Algorithmus |
ES384 | ECDSA verwendet P-384-Kurve und SHA-384-Hash-Algorithmus |
ES512 | ECDSA unter Verwendung der P-521-Kurve und des SHA-512-Hash-Algorithmus |
keiner | Keine digitale Signatur oder MAC-Wert enthalten |
Zunächst empfehlen wir Ihnen, sorgfältig zu überlegen, ob die automatische Aktualisierung eines JWT nicht zu einer Schwachstelle in Ihrem System führt.
Es ist uns unangenehm, dies als Teil der Bibliothek aufzunehmen. Sie können sich jedoch dieses Beispiel ansehen, um zu zeigen, wie dies erreicht werden könnte. Abgesehen von diesem Beispiel gibt es ein Problem und einen Pull-Request, um mehr über dieses Thema zu erfahren.
Die X.509-Zertifikatskette wird nicht überprüft
Wenn Sie einen Fehler gefunden haben oder eine Funktionsanfrage haben, melden Sie diese bitte in diesem Abschnitt zu Repository-Problemen. Bitte melden Sie Sicherheitslücken nicht im öffentlichen GitHub-Issue-Tracker. Das Responsible Disclosure Program beschreibt detailliert das Verfahren zur Offenlegung von Sicherheitsproblemen.
Auth0
Dieses Projekt ist unter der MIT-Lizenz lizenziert. Weitere Informationen finden Sie in der LICENSE-Datei.