Zum Inhalt springen
Aback Tools Logo

JWT-Konfiguration in TypeScript validieren: Algorithmen, Claims & Secrets

JWT-Konfiguration in TypeScript validieren: Algorithmen in jwt.verify() erzwingen, exp/nbf/iss/aud-Claims prüfen, Schlüssel mit JWKS rotieren und Tokens mit Browser-Tools debuggen.

DH
Tutorials & How-Tos12 Min. Lesezeit2,750 Wörter

Die meisten JWT-Bugs in TypeScript liegen nicht im Token — sie liegen in der Verifikationskonfiguration. Eine fehlende Algorithmus-Beschränkung, ein ungeprüfter Issuer-Claim oder ein kurzlebiges Secret kann die Authentifizierung still untergraben, und das nur in der Produktion offenbart. Dieser Leitfaden führt durch jede Dimension der korrekten JWT-Konfiguration in TypeScript: Algorithmen, Claim-Validierung, Secret-Hygiene, Ablauf-Handhabung und die Browser-Tools, die das Debuggen beschleunigen.

3JWT-Header-TeileHeader · Payload · Signatur
RS256Empfohlener AlgorithmusAsymmetrisch, produktions sicher
0 KBServer-UploadsJWT-Debugging im Browser

Was die Validierung der JWT-Konfiguration abdeckt

Ein JSON Web Token (JWT) ist eine kompakte, URL-sichere Zeichenkette aus drei Base64URL-kodierten Teilen, getrennt durch Punkte: ein Header, der Algorithmus und Tokentyp deklariert, ein Payload mit den Claims und eine Signatur, die beide verbindet. Ein JWT zu validieren bedeutet zu bestätigen, dass alle drei Teile intakt sind und die Claims die Anforderungen Ihrer Anwendung erfüllen — nicht nur, dass die Signatur mathematisch korrekt ist.

Die zwei Schichten der JWT-Validierung

Die kryptografische Validierung bestätigt die Signatur: Der Server prüft, dass das Token mit dem erwarteten Schlüssel signiert und nicht manipuliert wurde. Die Konfigurationsvalidierung geht weiter: Sie prüft, dass das Token von der richtigen Instanz ausgestellt wurde, für genau diesen Dienst bestimmt ist, nicht abgelaufen ist und die erwarteten benutzerdefinierten Claims trägt. Die meisten JWT-Sicherheitslücken entstehen durch unvollständige Konfigurationsvalidierung, nicht durch gebrochene Kryptografie.

  • Algorithmus (`alg`) - muss exakt Ihrer Serverkonfiguration entsprechen; nie aus dem Token-Header ableiten
  • Ablauf (`exp`) - das Token darf seinen Ablaufzeitpunkt nicht überschritten haben, mit Uhrentoleranz
  • Nicht-vor (`nbf`) - das Token darf vor seiner frühesten gültigen Zeit nicht verwendet werden
  • Issuer (`iss`) - das Token muss von Ihrem vertrauenswürdigen Auth-Dienst stammen
  • Audience (`aud`) - das Token muss für genau diese API oder diesen Dienst bestimmt sein
  • Benutzerdefinierte Claims - Rolle, Scope, Tenant-ID oder jedes anwendungsspezifische Feld, von dem Ihre Logik abhängt

Note

Die Validierung der JWT-Struktur (Prüfung, dass das Token ein gültiger dreiteiliger Base64URL-String ist) ist Voraussetzung für alle weiteren Validierungen. Der [JWT-Decoder und -Validator](/tools/data/validators/jwt-decoder-and-validator) erledigt das sofort im Browser — nützlich, um vor dem Schreiben von Verifikationscode zu bestätigen, dass ein Token wohlgeformt ist.

Prüfungen zu Algorithmus und Schlüsselkonfiguration

Die Algorithmus-Konfiguration ist die sicherheitskritischste Einstellung in der JWT-Verifikation. Wird sie falsch gesetzt, entsteht eine Angriffsklasse, die die Authentifizierung vollständig umgeht. TypeScript-JWT-Bibliotheken geben Ihnen die Werkzeuge, sie korrekt zu erzwingen — aber nur, wenn Sie sie explizit verwenden.

HS256 vs. RS256 — den richtigen Algorithmus wählen

EigenschaftHS256 (symmetrisch)RS256 (asymmetrisch)
SchlüsseltypGemeinsames Secret (gleicher Schlüssel zum Signieren + Verifizieren)RSA-Schlüsselpaar (privat zum Signieren, öffentlich zum Verifizieren)
SchlüsselverteilungJeder Verifizierer besitzt das SecretNur der Issuer besitzt den privaten Schlüssel
Multi-Service-Sicherheit✗ Riskant — alle Verifizierer können Tokens fälschen✓ Verifizierer besitzen nur den öffentlichen Schlüssel
OIDC-/JWKS-Unterstützung✗ Nicht anwendbar✓ Öffentliche Schlüssel über JWKS-Endpunkt bereitgestellt
Leistung✓ Schnell (HMAC)✗ Langsamer (RSA-Mathematik)
Am besten fürInterne Werkzeuge, Single-Service-APIsProduktions-APIs, verteilte Systeme, OIDC

Der Algorithmus-Confusion-Angriff — und wie man ihn verhindert

Algorithmus-Verwirrung entsteht, wenn ein Server das Feld `alg` aus dem JWT-Header liest, um zu entscheiden, wie das Token verifiziert wird, statt den Algorithmus aus der eigenen Konfiguration zu erzwingen. Ein Angreifer ändert den Header von `RS256` auf `HS256` und signiert das Token dann mit dem öffentlichen Schlüssel des Servers als HMAC-Secret. Ein falsch konfigurierter Server akzeptiert es als gültig. Die Korrektur ist eine einzelne Codezeile — aber sie muss vorhanden sein.

typescript
// ✗ Vulnerable - algorithm inferred from token header
jwt.verify(token, publicKey);

// ✓ Correct - algorithm enforced from server configuration
jwt.verify(token, publicKey, { algorithms: ['RS256'] });

Warning

Lassen Sie die Option `algorithms` in `jwt.verify()` niemals weg. Selbst wenn Ihre aktuelle Bibliotheksversion den `none`-Algorithmus standardmäßig ablehnt, macht das explizite Auflisten der erlaubten Algorithmen in Ihrem Code die Absicht klar, überlebt Bibliotheksupgrades und eliminiert die Angriffsklasse der Algorithmus-Verwirrung vollständig.

Validierung der Schlüsselstärke für HS256

Bei HS256 muss das Secret mindestens 256 Bit (32 Bytes) betragen, um der Ausgabegröße von SHA-256 zu entsprechen. Kurze Secrets — weniger als 32 Zeichen, Wörterbuchwörter oder statische Strings wie `"secret"` oder `"development"` — lassen sich mit Werkzeugen wie `hashcat` oder `jwt_tool` trivial per Brute Force knacken. Erzeugen Sie Secrets mit einer kryptografisch sicheren Zufallsquelle: `crypto.randomBytes(32).toString('hex')` in Node.js liefert einen 64 Zeichen langen Hex-String, der die minimale Entropieanforderung erfüllt.

Standard-JWT-Claims in TypeScript validieren

Die JWT-Spezifikation definiert eine Menge standardmäßiger registrierter Claims, die jede Implementierung verstehen sollte. Die Bibliothek `jsonwebtoken` validiert mehrere davon automatisch, wenn Sie die richtigen Optionen übergeben — aber das Schlüsselwort ist „wenn Sie sie übergeben“. Ohne explizite Konfiguration werden die meisten Claim-Prüfungen still übersprungen.

Die Claims exp, nbf und iat

Der exp-Claim (Ablauf) ist ein Unix-Zeitstempel, nach dem das Token nicht mehr gültig ist. Die jsonwebtoken-Bibliothek prüft exp standardmäßig während jwt.verify(). Allerdings kann die Uhrabweichung zwischen Token-Issuer und Verifizierer dazu führen, dass gültige Tokens abgelehnt werden — eine häufige Ursache für „Token abgelaufen“-Fehler in verteilten Systemen, in denen Serveruhren um Sekunden abweichen. Übergeben Sie clockTolerance, um ein kleines Fenster zuzulassen: clockTolerance = 30 akzeptiert Tokens bis 30 Sekunden nach ihrem exp-Wert.

typescript
interface JwtPayload {
  sub: string;
  iss: string;
  aud: string;
  exp: number;
  iat: number;
  role: 'admin' | 'user';
}

const payload = jwt.verify(token, publicKey, {
  algorithms: ['RS256'],
  issuer: 'https://auth.example.com',
  audience: 'api.example.com',
  clockTolerance: 30,           // seconds of clock skew to tolerate
}) as JwtPayload;

Die Claims iss und aud

Der `iss`-Claim (Issuer) identifiziert die Herkunft des Tokens. Der `aud`-Claim (Audience) identifiziert den vorgesehenen Empfänger. Beide sind in der JWT-Spezifikation optional, in der Praxis aber kritisch. Ohne `iss`-Validierung kann jeder Dienst, der gültige Tokens mit Ihrem Signaturschlüssel erzeugen kann, sich an Ihrer API authentifizieren. Ohne `aud`-Validierung kann ein Token für Ihre mobile App gegen Ihre Admin-API wiederverwendet werden. Übergeben Sie beide als Optionen an `jwt.verify()`, damit die Bibliothek sie als harte Anforderungen erzwingt statt als informative Felder.

Tip

Prüfen Sie die `iss`- und `aud`-Werte eines empfangenen Tokens, indem Sie es in den [JWT-Decoder und -Validator](/tools/data/validators/jwt-decoder-and-validator) einfügen. Das dekodierte Payload zeigt jeden Claim in lesbarer Form — so lässt sich leicht bestätigen, dass Ihre Issuer- und Audience-Strings dem entsprechen, was die Bibliothek erwartet.

JWT-Validierung in TypeScript implementieren

Eine vollständige JWT-Verifikationsfunktion in TypeScript behandelt kryptografische Validierung, Claim-Validierung und Fehlerklassifizierung an einem Ort. So strukturieren Sie sie — mit den vier Schritten, die zum HowTo-Schema passen.

1

Prüfen Sie, dass der Algorithmus zu Ihrem Schlüsseltyp passt

Bevor Sie Verifikationscode schreiben, bestätigen Sie Ihre Kombination aus Algorithmus und Schlüssel. RS256 benötigt einen RSA-Privatschlüssel zum Signieren und den zugehörigen öffentlichen Schlüssel zum Verifizieren. HS256 benötigt beidseitig dasselbe gemeinsame Secret. Verwechselt man sie, entstehen Laufzeitausnahmen, die schwer zu diagnostizieren sind. Speichern Sie Ihren öffentlichen Schlüssel oder Ihr Secret in Umgebungsvariablen — nie im Quellcode hart verankern.

2

Validieren Sie die Claims exp und nbf explizit

Setzen Sie immer `clockTolerance`, um kleine Uhrabweichungen zwischen Diensten zu handhaben. Ein Wert von 30 Sekunden ist für die meisten verteilten Systeme ein vernünftiger Standard. Beim Debuggen von `TokenExpiredError` in der Produktion loggen Sie `payload.exp * 1000` und `Date.now()` zusammen — das zeigt exakt, wie viele Millisekunden das Token über den Ablauf hinaus alt war, und unterscheidet echten Ablauf von einem Uhren-Synchronisierungsproblem zwischen Ihrem Auth-Dienst und dem API-Server.

3

Prüfen Sie die Claims iss und aud gegen erwartete Werte

Übergeben Sie die Optionen `issuer` und `audience` an `jwt.verify()`, damit die Bibliothek Tokens mit abweichenden Werten ablehnt, bevor Ihr Anwendungscode läuft. Hat Ihr System mehrere gültige Audiences (z. B. sowohl `api.example.com` als auch `admin.example.com`), übergeben Sie ein Array: `audience: ['api.example.com', 'admin.example.com']`. Die Bibliothek akzeptiert das Token, wenn der `aud`-Claim einem der Array-Einträge entspricht.

4

Testen Sie Ihre Konfiguration mit dem JWT-Decoder

Bevor Sie Ihre TypeScript-Testsuite ausführen, fügen Sie ein Beispiel-Token aus Ihrer Entwicklungs- oder Staging-Umgebung in den JWT-Decoder und -Validator ein. Bestätigen Sie visuell, dass jeder Claim — `alg`, `exp`, `iss`, `aud` und Ihre benutzerdefinierten Claims — den Optionen Ihres `jwt.verify()` entspricht. Diese Ein-Minuten-Prüfung findet Abweichungen zwischen Tokeninhalt und Codeerwartung, bevor Sie Zeit in einer Testumgebung debuggen.

JWT-Decoder und -Validator

Dekodieren Sie JWT-Tokens und prüfen Sie alle Claims, Header-Felder und häufige Sicherheitsprobleme sofort im Browser — ohne Registrierung, ohne Server-Upload.

Open tool

Häufige Fehler in der JWT-Konfiguration

Dies sind die Konfigurationsfehler, die in TypeScript-JWT-Implementierungen am häufigsten auftreten. Jeder davon ist beim Start still und zeigt sich erst als Authentifizierungsfehler oder Sicherheitsvorfall in der Produktion.

`jwt.decode()` statt `jwt.verify()` verwenden

Die Funktion `jwt.decode()` extrahiert das Payload, ohne die Signatur zu prüfen. Sie ist nützlich, um ein bereits vertrauenswürdiges Token zu inspizieren — etwa eine Benutzer-ID aus einem Token zu lesen, das bereits vom Middleware validiert wurde. Sie ist kein Ersatz für `jwt.verify()`. Code, der mit `jwt.decode()` Claims gewinnt und darauf Autorisierungsentscheidungen stützt, akzeptiert unverifizierte Tokens. Das ist eine vollständige Umgehung der Authentifizierung.

Den Fehlertyp in catch-Blöcken ignorieren

Die Bibliothek `jsonwebtoken` wirft drei verschiedene Fehlertypen: `JsonWebTokenError` (fehlerhaftes Token oder ungültige Signatur), `TokenExpiredError` (über den `exp`-Claim hinaus) und `NotBeforeError` (vor dem `nbf`-Claim). Alle Fehler als generisches `Error` zu fangen und in allen Fällen `401 Unauthorized` zurückzugeben, verliert Diagnoseinformationen. Behandeln Sie jeden Typ separat und geben Sie spezifische Meldungen zurück — `Token abgelaufen` gegenüber `ungültiges Token` —, damit Clients und Monitoring-Systeme Konfigurationsprobleme von echten Angriffsversuchen unterscheiden können.

Secrets oder Schlüsselpaare nicht rotieren

Langlebige Signing-Secrets häufen mit der Zeit Risiko an. Ein nie rotiertes Secret bedeutet, dass jedes je damit ausgestellte Token gültig bleibt, falls das Secret kompromittiert wird. Implementieren Sie ein Schlüssel-ID-Feld (`kid`) in Ihrem JWT-Header, damit der Verifizierer den richtigen öffentlichen Schlüssel aus einem JWKS-Endpunkt nachschlagen kann. Dieses Muster erlaubt Schlüsselrotation, ohne Tokens zu invalidieren, die vom vorherigen Schlüssel signiert wurden — jedes Token trägt eine Referenz auf den konkreten Schlüssel, der es signiert hat. Der JWK-Inspector hilft, die JWKS-Endpunkt-Ausgabe zu validieren und privates Schlüsselmaterial zu entdecken, das nicht öffentlich exponiert sein sollte.

Warning

Committen Sie niemals JWT-Secrets oder private Schlüssel in die Versionskontrolle. Verwenden Sie Umgebungsvariablen für alles Schlüsselmaterial, laden Sie sie zur Laufzeit und bestätigen Sie, dass sie gesetzt sind, bevor Sie Anfragen akzeptieren. Eine Anwendung, die mit einem undefinierten oder leeren Secret startet, akzeptiert still Tokens, die mit einem leeren String signiert sind.

Den `none`-Algorithmus akzeptieren

Der `none`-Algorithmus erzeugt ein unsigniertes JWT — jedes Payload mit gültiger Struktur besteht die Verifikation. Frühe JWT-Bibliotheksversionen akzeptierten `none` standardmäßig. Moderne Bibliotheken lehnen es ab, aber nur, wenn Sie die erlaubten Algorithmen in den Verify-Optionen explizit angeben. Fügen Sie immer `algorithms: ['RS256']` (oder Ihren konkreten Algorithmus) hinzu, um die Ablehnung von `none` explizit und resistent gegen Bibliotheksversionsänderungen zu machen.

JWT-Probleme mit Browser-Tools debuggen

Einen Test zu schreiben, um einen JWT-Fehler zu reproduzieren, ist oft langsamer, als das Token direkt zu inspizieren. Browserbasierte Werkzeuge lassen Sie Claims, Ablaufzustand und Schlüsselstruktur eines Tokens in Sekunden prüfen — ohne lokale Umgebung, ohne Codeausführung und ohne Übermittlung sensibler Daten an einen Drittanbieter.

Claims dekodieren und inspizieren

Der JWT-Decoder und -Validator dekodiert Header und Payload jedes JWT-Strings und präsentiert alle Claims in einem strukturierten, lesbaren Format. Er prüft auf häufige Sicherheitsprobleme — fehlendes `exp`, schwacher Algorithmus, fehlendes `aud` — und markiert sie mit klaren Diagnosen. Fügen Sie ein Token aus Ihrer Entwicklungs-, Staging- oder Produktionsumgebung ein und bestätigen Sie in zehn Sekunden, ob die Claims dem entsprechen, was Ihr `jwt.verify()`-Aufruf erwartet.

Ablaufprobleme diagnostizieren

Der JWT-Ablauf-Countdown-Rechner liest den `exp`-Claim aus jedem Token und zeigt die exakte verbleibende Lebensdauer oder die Zeit seit Ablauf in UTC und Lokalzeit. Meldet ein Benutzer „Token abgelaufen“, Ihre Logs aber zeigen, dass das Token noch gültig sein sollte, fügen Sie es in den Rechner ein. Der Millisekunden-genue Zeitstempelvergleich zeigt, ob es ein echter Ablauf, eine Uhrenabweichung zwischen Diensten oder ein in Millisekunden statt Sekunden gespeicherter `exp`-Wert ist — ein erstaunlich häufiger Faktor-1000-Bug.

JWKS-Schlüsselmengen inspizieren

Beim Validieren von Tokens eines OIDC-Providers oder eines Dienstes mit JWKS-Endpunkt parst und validiert der JWK-Inspector die Schlüsselmengenstruktur. Er prüft, dass jeder Schlüssel die Pflichtfelder (`kty`, `use`, `alg`, `kid`) hat, validiert Schlüsseltyp und Kurve für EC-Schlüssel und markiert privates Schlüsselmaterial, das nicht öffentlich exponiert sein sollte. Fügen Sie das JSON Ihres JWKS-Endpunkts direkt in das Werkzeug ein oder geben Sie die URL für einen Abruf an.

JWT-Ablauf-Countdown-Rechner

Berechnen Sie den exakten JWT-Ablauf-Countdown aus dem exp-Claim — sehen Sie die verbleibende Zeit oder die Zeit seit Ablauf in UTC und Lokalzeit, ohne Code.

Open tool

Best Practices für die JWT-Validierung

Eine korrekt konfigurierte JWT-Verifikationsfunktion ist notwendig, aber nicht ausreichend für sichere Authentifizierung. Diese Praktiken vervollständigen das Bild für TypeScript-Produktionsdienste.

Verwenden Sie eine typisierte Payload-Schnittstelle

Definieren Sie eine TypeScript-Schnittstelle für Ihr JWT-Payload und casten Sie das Verifikationsergebnis darauf. Das gibt Ihnen Kompilierzeit-Sicherheit bei Claim-Namen und Wertetypen — ein falsch geschriebener Claim-Name (`userId` vs. `user_id`) wird zu einem TypeScript-Fehler statt zu einem stillen `undefined` zur Laufzeit. Halten Sie die Schnittstelle in einem gemeinsamen Typmodell, damit sie in allen Diensten konsistent ist, die dasselbe Tokenformat verifizieren.

Kurze Token-Lebensdauern mit Refresh-Tokens

Access-Tokens sollten kurze Lebensdauern haben — 15 Minuten bis 1 Stunde für die meisten APIs. Langlebige Access-Tokens (Tage, Wochen) vergrößern das Fenster, in dem ein kompromittiertes Token nutzbar ist. Nutzen Sie einen separaten Refresh-Token-Fluss mit langer Ablaufzeit für die Sitzungspersistenz. Das Refresh-Token rotiert bei jeder Nutzung, und Sperrlisten sind nur für Refresh-Tokens nötig — nicht für Access-Tokens —, solange die Lebensdauern kurz gehalten werden.

Verifikationslogik zentralisieren

Schreiben Sie die JWT-Verifikation an einem Ort — eine Middleware-Funktion oder eine gemeinsame Utility — und verwenden Sie sie überall. Duplizierte Verifikationslogik lädt zu Konfigurationsdrift ein: ein Endpoint prüft `aud`, ein anderer vergisst es, und die Inkonsistenz wird ausgenutzt, bevor jemand es bemerkt. Express-Middleware, NestJS-Guards und Next.js-Route-Handler haben alle saubere Muster, um Auth-Prüfungen zu zentralisieren. Legen Sie Ihre Optionen `algorithms`, `issuer` und `audience` in ein einziges Konfigurationsobjekt, das im gesamten Code importiert wird.

Konfigurieren Sie die Verifikation einmal, erzwingen Sie sie überall. Die einzige JWT-Option, die sich zwischen Endpunkten unterscheiden darf, ist die erwartete Audience.

- Prinzip der sicheren JWT-Implementierung

Tip

Wenn Sie einen neuen Auth-Provider einführen oder Ihre JWT-Bibliothek aktualisieren, nutzen Sie den [JWT-Decoder und -Validator](/tools/data/validators/jwt-decoder-and-validator), um Tokens der neuen Quelle zu inspizieren, bevor Sie Ihre Verifikationskonfiguration anpassen. So bestätigen Sie die exakten `alg`-, `iss`- und `aud`-Werte der neuen Tokens, sodass Ihre Codeänderungen der Realität entsprechen — nicht Annahmen.

Key takeaways

  • Übergeben Sie `algorithms: ['RS256']` (oder Ihren konkreten Algorithmus) immer explizit an `jwt.verify()` — lassen Sie die Bibliothek ihn nie aus dem Token-Header ableiten.
  • Validieren Sie die Claims `iss` und `aud` bei jedem Verifikationsaufruf; das Weglassen erlaubt Tokens aus anderen Diensten, sich an Ihrer API zu authentifizieren.
  • Nutzen Sie `clockTolerance` für Uhrenabweichungen zwischen verteilten Diensten und loggen Sie `exp`-Zeitstempel neben `Date.now()`, wenn Sie Ablauf-Fehler debuggen.
  • Verwenden Sie `jwt.decode()` nie für Autorisierungsentscheidungen — es überspringt die Signaturprüfung vollständig und akzeptiert jedes Token-Payload.
  • Der JWT-Decoder und -Validator lässt Sie alle Claims prüfen und Konfigurationsprobleme in Sekunden markieren — ohne Code schreiben oder ausführen.
  • RS256 ist für Produktions-APIs HS256 vorzuziehen — es eliminiert das Verteilungsrisiko gemeinsamer Secrets und unterstützt JWKS-basierte Schlüsselrotation.
  • Halten Sie die Lebensdauern von Access-Tokens kurz (15-60 Minuten) und zentralisieren Sie die gesamte Verifikationslogik in einer einzigen Middleware oder Utility, um Konfigurationsdrift zu verhindern.

Häufige Fragen

Use the `jsonwebtoken` library (or `jose` for a modern alternative) and call `jwt.verify(token, secret, { algorithms: ['RS256'], issuer: 'your-issuer', audience: 'your-audience' })`. Always specify the `algorithms` array explicitly - never allow the library to infer it from the token header, as this enables algorithm confusion attacks. Wrap the call in a try/catch and handle `JsonWebTokenError`, `TokenExpiredError`, and `NotBeforeError` separately so you can return informative error responses to API clients.

An algorithm confusion attack occurs when a server accepts the `alg` field from the JWT header to determine how to verify the signature, rather than enforcing the algorithm from its own configuration. An attacker can change `alg` from `RS256` to `HS256` in the header, sign the token with the server's public key as the HMAC secret, and the server will incorrectly validate it as legitimate. The fix: always pass `algorithms: ['RS256']` (or your specific algorithm) explicitly in the verify options.

Call `jwt.verify()` - it throws a `TokenExpiredError` if the `exp` claim is in the past. To inspect expiry without throwing, decode the payload with `jwt.decode(token)` and compare `payload.exp * 1000` to `Date.now()`. For a visual expiry check without writing code, paste your token into the Aback Tools JWT Expiry Countdown Calculator, which shows the exact remaining time or time since expiry in both UTC and local time.

Yes - both are critical. The `iss` (issuer) claim identifies who created the token. Without verifying it, your application will accept tokens issued by any service, including attackers. The `aud` (audience) claim identifies the intended recipient. Without verifying it, a token issued for one of your services can be replayed against another. Pass both as options: `{ issuer: 'https://auth.example.com', audience: 'api.example.com' }`.

HS256 (HMAC-SHA256) uses a single shared secret for both signing and verification. It is simpler to implement but requires every service that verifies tokens to hold the same secret - a security risk in distributed systems. RS256 (RSA-SHA256) uses a private key to sign and a public key to verify. Only the issuing service holds the private key; all consuming services use the public key. RS256 is the recommended algorithm for production APIs where tokens are verified by multiple services or third parties.

After `jwt.verify()` succeeds, cast the result to a typed interface and assert your custom claim values. For example: `const payload = jwt.verify(token, secret) as MyPayload; if (payload.role !== 'admin') throw new Error('Insufficient role')`. Using a TypeScript interface for your JWT payload type gives you compile-time safety on claim names and value types. Validate any claim whose absence or wrong value would represent a security failure - not just standard claims.

The `jose` library is a modern, standards-compliant implementation of JWT, JWS, JWE, JWK, and JWKS that works in Node.js, browsers, Deno, and edge runtimes like Cloudflare Workers. Use `jose` when you need JWKS endpoint support for OIDC, when building for edge or serverless environments, or when you need JWE (encrypted JWT) support. Use `jsonwebtoken` for simple HS256 or RS256 signing and verification in traditional Node.js backends where a shared-secret or static key is sufficient.

Paste the JWT into the Aback Tools JWT Decoder and Validator at abacktools.com/tools/data/validators/jwt-decoder-and-validator. It decodes the header and payload, shows all claims in a readable format, checks for common configuration issues, and flags security problems - all in your browser with no server upload. For expiry checks, the JWT Expiry Countdown Calculator shows exactly how much time remains or how long ago the token expired.

ShareXLinkedIn