@jjlmoya/utils-developer 1.15.0 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/category/index.ts +3 -1
- package/src/entries.ts +7 -1
- package/src/index.ts +4 -0
- package/src/tests/locale_completeness.test.ts +2 -3
- package/src/tests/pagespeed_best_practices.test.ts +198 -0
- package/src/tests/tool_validation.test.ts +2 -2
- package/src/tool/aspectRatio/component.astro +3 -1
- package/src/tool/colorConverter/component.astro +3 -3
- package/src/tool/jwtDecoder/bibliography.astro +14 -0
- package/src/tool/jwtDecoder/bibliography.ts +12 -0
- package/src/tool/jwtDecoder/component.astro +209 -0
- package/src/tool/jwtDecoder/entry.ts +30 -0
- package/src/tool/jwtDecoder/i18n/de.ts +248 -0
- package/src/tool/jwtDecoder/i18n/en.ts +247 -0
- package/src/tool/jwtDecoder/i18n/es.ts +248 -0
- package/src/tool/jwtDecoder/i18n/fr.ts +248 -0
- package/src/tool/jwtDecoder/i18n/id.ts +248 -0
- package/src/tool/jwtDecoder/i18n/it.ts +248 -0
- package/src/tool/jwtDecoder/i18n/ja.ts +248 -0
- package/src/tool/jwtDecoder/i18n/ko.ts +248 -0
- package/src/tool/jwtDecoder/i18n/nl.ts +247 -0
- package/src/tool/jwtDecoder/i18n/pl.ts +247 -0
- package/src/tool/jwtDecoder/i18n/pt.ts +247 -0
- package/src/tool/jwtDecoder/i18n/ru.ts +248 -0
- package/src/tool/jwtDecoder/i18n/sv.ts +248 -0
- package/src/tool/jwtDecoder/i18n/tr.ts +248 -0
- package/src/tool/jwtDecoder/i18n/zh.ts +248 -0
- package/src/tool/jwtDecoder/index.ts +11 -0
- package/src/tool/jwtDecoder/jwt-decoder-parser-and-claims-inspector.css +358 -0
- package/src/tool/jwtDecoder/logic.ts +96 -0
- package/src/tool/jwtDecoder/seo.astro +15 -0
- package/src/tool/jwtDecoder/ui.ts +38 -0
- package/src/tool/llmCostCalculator/component.astro +1 -2
- package/src/tool/mobileMockupGenerator/component.astro +4 -5
- package/src/tool/placeholderGenerator/component.astro +2 -2
- package/src/tool/readabilityCalculator/component.astro +4 -4
- package/src/tool/serpPixelSimulator/bibliography.astro +14 -0
- package/src/tool/serpPixelSimulator/bibliography.ts +16 -0
- package/src/tool/serpPixelSimulator/component.astro +84 -0
- package/src/tool/serpPixelSimulator/controller.ts +323 -0
- package/src/tool/serpPixelSimulator/entry.ts +30 -0
- package/src/tool/serpPixelSimulator/i18n/de.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/en.ts +213 -0
- package/src/tool/serpPixelSimulator/i18n/es.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/fr.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/id.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/it.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/ja.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/ko.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/nl.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/pl.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/pt.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/ru.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/sv.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/tr.ts +214 -0
- package/src/tool/serpPixelSimulator/i18n/zh.ts +214 -0
- package/src/tool/serpPixelSimulator/index.ts +8 -0
- package/src/tool/serpPixelSimulator/logic.ts +18 -0
- package/src/tool/serpPixelSimulator/seo.astro +15 -0
- package/src/tool/serpPixelSimulator/serp-pixel-simulator.css +335 -0
- package/src/tool/serpPixelSimulator/ui.ts +33 -0
- package/src/tools.ts +3 -2
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { JwtDecoderUI } from '../ui';
|
|
4
|
+
import { bibliography } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'jwt-decoder-parser-und-claims-inspektor';
|
|
7
|
+
const title = 'JWT Decoder, Parser und Claims Inspektor';
|
|
8
|
+
const description = 'Fügen Sie ein JSON Web Token ein, dekodieren Sie dessen Header und Payload sofort, inspizieren Sie registrierte Claims, erkennen Sie abgelaufene Tokens und kopieren Sie sauberes JSON zum Debuggen von Authentifizierungsabläufen.';
|
|
9
|
+
|
|
10
|
+
const howTo = [
|
|
11
|
+
{
|
|
12
|
+
name: 'Fügen Sie das JWT ein',
|
|
13
|
+
text: 'Kopieren Sie ein Token aus einem Authorization-Header, Cookie, Log-Eintrag oder Identitätsanbieter und fügen Sie es in das Eingabefeld ein.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'Lesen Sie den dekodierten Header und Payload',
|
|
17
|
+
text: 'Das Tool teilt das Token in Header, Payload und Signatur auf und stellt die JSON-Segmente in separaten Panels zur schnellen Inspektion dar.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'Überprüfen Sie wichtige Claims',
|
|
21
|
+
text: 'Prüfen Sie Algorithmus, Aussteller, Audience, Subjekt, Ausstellungszeit, Gültigkeitsbeginn und Ablaufzeit, ohne Unix-Timestamps manuell umzurechnen.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Kopieren Sie die benötigten Daten',
|
|
25
|
+
text: 'Kopieren Sie einen dekodierten Abschnitt oder die gesamte dekodierte Ausgabe, wenn Sie eine bereinigte Debugging-Momentaufnahme mit Ihrem Team teilen müssen.',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const faq = [
|
|
30
|
+
{
|
|
31
|
+
question: 'Beweist die Dekodierung eines JWT, dass das Token gültig ist?',
|
|
32
|
+
answer: 'Nein. Die Dekodierung zeigt nur den base64url-kodierten Header und Payload. Ein Token ist erst vertrauenswürdig, nachdem die Signatur, der Aussteller, die Audience, der Ablauf und zugehörige Claims von der Anwendung oder dem Identitätsanbieter validiert wurden.',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
question: 'Kann ich diesen JWT-Decoder für Access-Tokens und ID-Tokens verwenden?',
|
|
36
|
+
answer: 'Ja. Der Decoder eignet sich zur Inspektion von OAuth-Access-Tokens, OpenID-Connect-ID-Tokens, Session-Tokens und Service-zu-Service-Tokens, sofern sie das standardmäßige dreiteilige JWT-Format verwenden.',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
question: 'Warum verifiziert das Signatur-Panel das Token nicht?',
|
|
40
|
+
answer: 'Die JWT-Verifizierung erfordert das korrekte Secret, den öffentlichen Schlüssel oder die JWKS-Konfiguration. Dieses Tool konzentriert sich bewusst auf Dekodierung und Inspektion, damit Entwickler den Token-Inhalt einsehen können, ohne vorzutäuschen, dass eine sichtbare Signatur-Zeichenkette ein Gültigkeitsnachweis ist.',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
question: 'Was sollte ich zuerst prüfen, wenn ich ein JWT debugge?',
|
|
44
|
+
answer: 'Beginnen Sie mit exp, nbf, iss, aud und alg. Die meisten echten Produktionsprobleme stammen von abgelaufenen Tokens, Uhrenabweichungen, falschen Audience-Werten, unerwarteten Aussteller-URLs oder unsicheren Algorithmus-Annahmen.',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
const ui: JwtDecoderUI = {
|
|
49
|
+
tokenLabel: 'JWT-Token',
|
|
50
|
+
tokenPlaceholder: 'JWT hier einfügen: Header.Payload.Signatur',
|
|
51
|
+
sampleButton: 'Beispiel laden',
|
|
52
|
+
clearButton: 'Löschen',
|
|
53
|
+
statusWaiting: 'Fügen Sie ein Token ein, um dessen JSON-Header, Payload und Claims zu dekodieren.',
|
|
54
|
+
statusValid: 'JWT erfolgreich dekodiert.',
|
|
55
|
+
statusInvalid: 'Dies sieht nicht nach einem gültigen dreiteiligen JWT aus.',
|
|
56
|
+
statusExpired: 'JWT dekodiert, aber der exp-Claim ist bereits abgelaufen.',
|
|
57
|
+
statusUnsigned: 'JWT dekodiert, aber es ist nicht signiert oder verwendet den Algorithmus none.',
|
|
58
|
+
headerTitle: 'Header',
|
|
59
|
+
payloadTitle: 'Payload',
|
|
60
|
+
signatureTitle: 'Signatur',
|
|
61
|
+
claimsTitle: 'Registrierte Claims',
|
|
62
|
+
copyHeader: 'Dekodierten Header kopieren',
|
|
63
|
+
copyPayload: 'Dekodierten Payload kopieren',
|
|
64
|
+
copySignature: 'Signatur kopieren',
|
|
65
|
+
copyAll: 'Alles kopieren',
|
|
66
|
+
copiedLabel: 'Kopiert',
|
|
67
|
+
invalidTokenTitle: 'Ungültiges JWT',
|
|
68
|
+
invalidTokenBody: 'Prüfen Sie, ob das Token drei durch Punkte getrennte base64url-Segmente hat.',
|
|
69
|
+
invalidSegmentError: 'Prüfen Sie, ob das Token drei durch Punkte getrennte base64url-Segmente hat.',
|
|
70
|
+
invalidDecodeError: 'Der Header oder Payload konnte nicht als gültiges JSON dekodiert werden.',
|
|
71
|
+
emptyJson: '{}',
|
|
72
|
+
signaturePresent: 'Signatursegment ist vorhanden; verifizieren Sie es in Ihrer Authentifizierungsschicht mit dem richtigen Schlüssel.',
|
|
73
|
+
signatureMissing: 'Kein Signatursegment',
|
|
74
|
+
algorithmLabel: 'Algorithmus',
|
|
75
|
+
typeLabel: 'Typ',
|
|
76
|
+
issuerLabel: 'Aussteller',
|
|
77
|
+
subjectLabel: 'Subjekt',
|
|
78
|
+
audienceLabel: 'Audience',
|
|
79
|
+
issuedAtLabel: 'Ausgestellt am',
|
|
80
|
+
notBeforeLabel: 'Gültig ab',
|
|
81
|
+
expiresAtLabel: 'Läuft ab am',
|
|
82
|
+
claimMissing: 'Nicht vorhanden',
|
|
83
|
+
privacyNote: 'Die Dekodierung läuft in Ihrer Browser-Sitzung. Fügen Sie keine Produktionsgeheimnisse in ein Tool ein, es sei denn, Ihre Sicherheitsrichtlinie erlaubt dies.',
|
|
84
|
+
sampleToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJnYW1lYm9iLXVzZXItNDIiLCJuYW1lIjoiR2FtZUJvYiBEZXZlbG9wZXIiLCJpc3MiOiJodHRwczovL3d3dy5nYW1lYm9iLmRldiIsImF1ZCI6ImRldmVsb3Blci10b29scyIsImlhdCI6MTcxNzIwMDAwMCwibmJmIjoxNzE3MjAwMDAwLCJleHAiOjE4OTM0NTYwMDAsInJvbGUiOiJhZG1pbiJ9.demo-signature',
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
88
|
+
'@context': 'https://schema.org',
|
|
89
|
+
'@type': 'FAQPage',
|
|
90
|
+
mainEntity: faq.map((item) => ({
|
|
91
|
+
'@type': 'Question',
|
|
92
|
+
name: item.question,
|
|
93
|
+
acceptedAnswer: {
|
|
94
|
+
'@type': 'Answer',
|
|
95
|
+
text: item.answer,
|
|
96
|
+
},
|
|
97
|
+
})),
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const howToSchema: WithContext<HowTo> = {
|
|
101
|
+
'@context': 'https://schema.org',
|
|
102
|
+
'@type': 'HowTo',
|
|
103
|
+
name: title,
|
|
104
|
+
description,
|
|
105
|
+
step: howTo.map((step, index) => ({
|
|
106
|
+
'@type': 'HowToStep',
|
|
107
|
+
position: index + 1,
|
|
108
|
+
name: step.name,
|
|
109
|
+
text: step.text,
|
|
110
|
+
})),
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
114
|
+
'@context': 'https://schema.org',
|
|
115
|
+
'@type': 'SoftwareApplication',
|
|
116
|
+
name: title,
|
|
117
|
+
description,
|
|
118
|
+
applicationCategory: 'DeveloperApplication',
|
|
119
|
+
operatingSystem: 'Any',
|
|
120
|
+
offers: {
|
|
121
|
+
'@type': 'Offer',
|
|
122
|
+
price: '0',
|
|
123
|
+
priceCurrency: 'EUR',
|
|
124
|
+
},
|
|
125
|
+
inLanguage: 'de',
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export const content: ToolLocaleContent<JwtDecoderUI> = {
|
|
129
|
+
slug,
|
|
130
|
+
title,
|
|
131
|
+
description,
|
|
132
|
+
ui,
|
|
133
|
+
faqTitle: 'Häufig gestellte Fragen zum JWT-Decoder',
|
|
134
|
+
faq,
|
|
135
|
+
bibliographyTitle: 'JWT-Spezifikationen und Sicherheitsreferenzen',
|
|
136
|
+
bibliography,
|
|
137
|
+
howTo,
|
|
138
|
+
schemas: [appSchema, faqSchema, howToSchema],
|
|
139
|
+
seo: [
|
|
140
|
+
{
|
|
141
|
+
type: 'title',
|
|
142
|
+
text: 'JWTs dekodieren, ohne den Sicherheitskontext zu verlieren',
|
|
143
|
+
level: 2,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
type: 'paragraph',
|
|
147
|
+
html: 'Ein JSON Web Token wirkt kompakt, enthält aber oft genau das Detail, das einen Authentifizierungsfehler erklärt: den Signaturalgorithmus, den Aussteller, die Audience, das Subjekt, die Ausstellungszeit, die Gültigkeitsbeginnzeit, den Ablauf und anwendungsspezifische Autorisierungs-Claims. Dieser <strong>JWT-Decoder, Parser und Claims-Inspektor</strong> wandelt die drei Token-Segmente in lesbares JSON um, damit Sie Authentifizierungsabläufe schneller debuggen können.',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'diagnostic',
|
|
151
|
+
variant: 'warning',
|
|
152
|
+
title: 'Dekodiert bedeutet nicht vertrauenswürdig',
|
|
153
|
+
html: 'Jeder kann ein JWT base64url-dekodieren. Vertrauen beginnt erst, nachdem Ihre Anwendung die Signatur mit dem korrekten Secret, öffentlichen Schlüssel oder JWKS verifiziert und dann Aussteller, Audience, Ablauf und alle domainspezifischen Claims validiert hat. Verwenden Sie dieses Tool zur Dateninspektion, nicht um ein Token als authentisch zu akzeptieren.',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
type: 'title',
|
|
157
|
+
text: 'Was Ihnen jedes JWT-Segment verrät',
|
|
158
|
+
level: 3,
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: 'table',
|
|
162
|
+
headers: ['Segment', 'Typischer Inhalt', 'Debugging-Wert'],
|
|
163
|
+
rows: [
|
|
164
|
+
['Header', 'Algorithmus, Tokentyp und optionale Schlüssel-ID', 'Zeigt, ob das Token HS256, RS256, ES256 oder eine andere Verifikationsstrategie erwartet.'],
|
|
165
|
+
['Payload', 'Registrierte Claims und Anwendungs-Claims', 'Enthüllt Identität, Tenant, Scopes, Rollen, Ablauf und Audience-Abweichungen.'],
|
|
166
|
+
['Signatur', 'Kryptografische Signatur-Bytes als base64url kodiert', 'Bestätigt, dass ein Signatursegment existiert, muss aber mit dem richtigen Schlüssel anderweitig verifiziert werden.'],
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
type: 'title',
|
|
171
|
+
text: 'Claims, die meistens fehlerhafte Authentifizierung erklären',
|
|
172
|
+
level: 3,
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
type: 'list',
|
|
176
|
+
items: [
|
|
177
|
+
'<strong>exp:</strong> Wenn das Token abgelaufen ist, könnte die Aktualisierungslogik oder die Uhreneinstellung falsch sein.',
|
|
178
|
+
'<strong>nbf:</strong> Wenn das Token noch nicht aktiv ist, könnten die Uhren von Server und Identitätsanbieter nicht synchron sein.',
|
|
179
|
+
'<strong>iss:</strong> Wenn die Aussteller-URL von der Konfiguration abweicht, stammt das Token möglicherweise vom falschen Tenant oder aus der falschen Umgebung.',
|
|
180
|
+
'<strong>aud:</strong> Wenn die Audience nicht mit der API-Kennung übereinstimmt, wurde das Token für eine andere Ressource ausgestellt.',
|
|
181
|
+
'<strong>alg:</strong> Wenn der Algorithmus unerwartet ist, könnte Ihr Verifizierer das Token ablehnen oder einen gefährlichen Konfigurationsfehler aufdecken.',
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
type: 'title',
|
|
186
|
+
text: 'Anwendungsfälle für einen JWT-Parser während der Entwicklung',
|
|
187
|
+
level: 3,
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
type: 'comparative',
|
|
191
|
+
columns: 3,
|
|
192
|
+
items: [
|
|
193
|
+
{
|
|
194
|
+
title: 'Frontend Debugging',
|
|
195
|
+
description: 'Inspizieren Sie ID-Tokens und Access-Tokens, die nach dem Login empfangen wurden, um Scopes, Rollen und Profil-Claims zu bestätigen.',
|
|
196
|
+
icon: 'mdi:monitor-dashboard',
|
|
197
|
+
points: ['Profil-Claims prüfen', 'Scopes und Rollen bestätigen', 'Login-Umgebungen vergleichen'],
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
title: 'Backend API QA',
|
|
201
|
+
description: 'Vergleichen Sie erwartete Aussteller- und Audience-Werte mit dem tatsächlich in einem Authorization-Header gesendeten Token.',
|
|
202
|
+
icon: 'mdi:api',
|
|
203
|
+
highlight: true,
|
|
204
|
+
points: ['Audience-Form validieren', 'Aussteller-Abweichungen erkennen', 'Bearer-Tokens inspizieren'],
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
title: 'Identitätsanbieter Einrichtung',
|
|
208
|
+
description: 'Prüfen Sie, ob Claims von Auth0, Azure AD, Cognito, Keycloak oder einem benutzerdefinierten Anbieter so geformt sind, wie Ihre App es erwartet.',
|
|
209
|
+
icon: 'mdi:account-key',
|
|
210
|
+
points: ['Tenant-Daten überprüfen', 'Benutzerdefinierte Claims prüfen', 'Anbieter-Zuordnungen vergleichen'],
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
type: 'title',
|
|
216
|
+
text: 'Häufige JWT-Fehler, die dieser Inspektor sichtbar macht',
|
|
217
|
+
level: 3,
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
type: 'proscons',
|
|
221
|
+
title: 'Schnelle Prüfungen gegen Vertrauensentscheidungen',
|
|
222
|
+
items: [
|
|
223
|
+
{
|
|
224
|
+
pro: 'Sehen Sie fehlerhafte Tokens sofort.',
|
|
225
|
+
con: 'Er kann Ihre erwartete Audience oder Ihren Aussteller nicht kennen.',
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
pro: 'Konvertieren Sie Unix-Timestamp-Claims in lesbare Datumsangaben.',
|
|
229
|
+
con: 'Er kann eine Signatur nicht ohne das echte Schlüsselmaterial verifizieren.',
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
pro: 'Erkennen Sie fehlende Aussteller-, Audience-, Subjekt- oder Typ-Werte.',
|
|
233
|
+
con: 'Er kann nicht beweisen, dass Scopes und Rollen für Ihre Anwendung sicher sind.',
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
type: 'summary',
|
|
239
|
+
title: 'Empfohlener Workflow',
|
|
240
|
+
items: [
|
|
241
|
+
'Dekodieren Sie das Token, um zu verstehen, was der Client oder die API tatsächlich erhalten hat.',
|
|
242
|
+
'Prüfen Sie exp, nbf, iss, aud, sub und alg, bevor Sie der Anwendungslogik nachgehen.',
|
|
243
|
+
'Verifizieren Sie Signaturen und Vertrauensentscheidungen nur in Ihrer Authentifizierungsschicht.',
|
|
244
|
+
'Vermeiden Sie die Weitergabe sensibler Produktions-JWTs in Tickets, Logs oder Screenshots.',
|
|
245
|
+
],
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
};
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { JwtDecoderUI } from '../ui';
|
|
4
|
+
import { bibliography } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'jwt-decoder-parser-and-claims-inspector';
|
|
7
|
+
const title = 'JWT Decoder, Parser and Claims Inspector';
|
|
8
|
+
const description = 'Paste a JSON Web Token, decode its header and payload instantly, inspect registered claims, spot expired tokens, and copy clean JSON for debugging authentication flows.';
|
|
9
|
+
|
|
10
|
+
const howTo = [
|
|
11
|
+
{
|
|
12
|
+
name: 'Paste the JWT',
|
|
13
|
+
text: 'Copy a token from an Authorization header, cookie, log entry or identity provider and paste it into the input field.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'Read the decoded header and payload',
|
|
17
|
+
text: 'The tool splits the token into header, payload and signature, then renders the JSON segments in separate panels for fast inspection.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'Check important claims',
|
|
21
|
+
text: 'Review algorithm, issuer, audience, subject, issued-at time, not-before time and expiration time without manually converting Unix timestamps.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Copy the data you need',
|
|
25
|
+
text: 'Copy one decoded section or the complete decoded output when you need to share a sanitized debugging snapshot with your team.',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const faq = [
|
|
30
|
+
{
|
|
31
|
+
question: 'Does decoding a JWT prove that the token is valid?',
|
|
32
|
+
answer: 'No. Decoding only reveals the base64url-encoded header and payload. A token is trustworthy only after the signature, issuer, audience, expiration and related claims are validated by the application or identity provider.',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
question: 'Can I use this JWT decoder for access tokens and ID tokens?',
|
|
36
|
+
answer: 'Yes. The decoder is useful for inspecting OAuth access tokens, OpenID Connect ID tokens, session tokens and service-to-service tokens, as long as they use the standard three-part JWT format.',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
question: 'Why does the signature panel not verify the token?',
|
|
40
|
+
answer: 'JWT verification requires the correct secret, public key or JWKS configuration. This tool intentionally focuses on decoding and inspection so developers can see token contents without pretending that a visible signature string is proof of validity.',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
question: 'What should I check first when debugging a JWT?',
|
|
44
|
+
answer: 'Start with exp, nbf, iss, aud and alg. Most real production issues come from expired tokens, clock skew, wrong audience values, unexpected issuer URLs or insecure algorithm assumptions.',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
const ui: JwtDecoderUI = {
|
|
49
|
+
tokenLabel: 'JWT token',
|
|
50
|
+
tokenPlaceholder: 'Paste a JWT here: header.payload.signature',
|
|
51
|
+
sampleButton: 'Load sample',
|
|
52
|
+
clearButton: 'Clear',
|
|
53
|
+
statusWaiting: 'Paste a token to decode its JSON header, payload and claims.',
|
|
54
|
+
statusValid: 'JWT decoded successfully.',
|
|
55
|
+
statusInvalid: 'This does not look like a valid three-part JWT.',
|
|
56
|
+
statusExpired: 'JWT decoded, but the exp claim is already expired.',
|
|
57
|
+
statusUnsigned: 'JWT decoded, but it is unsigned or uses alg none.',
|
|
58
|
+
headerTitle: 'Header',
|
|
59
|
+
payloadTitle: 'Payload',
|
|
60
|
+
signatureTitle: 'Signature',
|
|
61
|
+
claimsTitle: 'Registered claims',
|
|
62
|
+
copyHeader: 'Copy decoded header',
|
|
63
|
+
copyPayload: 'Copy decoded payload',
|
|
64
|
+
copySignature: 'Copy signature',
|
|
65
|
+
copyAll: 'Copy all',
|
|
66
|
+
copiedLabel: 'Copied',
|
|
67
|
+
invalidTokenTitle: 'Invalid JWT',
|
|
68
|
+
invalidTokenBody: 'Check that the token has three dot-separated base64url segments.',
|
|
69
|
+
invalidSegmentError: 'Check that the token has three dot-separated base64url segments.',
|
|
70
|
+
invalidDecodeError: 'The header or payload could not be decoded as valid JSON.',
|
|
71
|
+
emptyJson: '{}',
|
|
72
|
+
signaturePresent: 'Signature segment is present; verify it in your auth layer with the correct key.',
|
|
73
|
+
signatureMissing: 'No signature segment',
|
|
74
|
+
algorithmLabel: 'Algorithm',
|
|
75
|
+
typeLabel: 'Type',
|
|
76
|
+
issuerLabel: 'Issuer',
|
|
77
|
+
subjectLabel: 'Subject',
|
|
78
|
+
audienceLabel: 'Audience',
|
|
79
|
+
issuedAtLabel: 'Issued at',
|
|
80
|
+
notBeforeLabel: 'Not before',
|
|
81
|
+
expiresAtLabel: 'Expires at',
|
|
82
|
+
claimMissing: 'Not present',
|
|
83
|
+
privacyNote: 'Decoding runs in your browser session. Do not paste production secrets into any tool unless your security policy allows it.',
|
|
84
|
+
sampleToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJnYW1lYm9iLXVzZXItNDIiLCJuYW1lIjoiR2FtZUJvYiBEZXZlbG9wZXIiLCJpc3MiOiJodHRwczovL3d3dy5nYW1lYm9iLmRldiIsImF1ZCI6ImRldmVsb3Blci10b29scyIsImlhdCI6MTcxNzIwMDAwMCwibmJmIjoxNzE3MjAwMDAwLCJleHAiOjE4OTM0NTYwMDAsInJvbGUiOiJhZG1pbiJ9.demo-signature',
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
88
|
+
'@context': 'https://schema.org',
|
|
89
|
+
'@type': 'FAQPage',
|
|
90
|
+
mainEntity: faq.map((item) => ({
|
|
91
|
+
'@type': 'Question',
|
|
92
|
+
name: item.question,
|
|
93
|
+
acceptedAnswer: {
|
|
94
|
+
'@type': 'Answer',
|
|
95
|
+
text: item.answer,
|
|
96
|
+
},
|
|
97
|
+
})),
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const howToSchema: WithContext<HowTo> = {
|
|
101
|
+
'@context': 'https://schema.org',
|
|
102
|
+
'@type': 'HowTo',
|
|
103
|
+
name: title,
|
|
104
|
+
description,
|
|
105
|
+
step: howTo.map((step, index) => ({
|
|
106
|
+
'@type': 'HowToStep',
|
|
107
|
+
position: index + 1,
|
|
108
|
+
name: step.name,
|
|
109
|
+
text: step.text,
|
|
110
|
+
})),
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
114
|
+
'@context': 'https://schema.org',
|
|
115
|
+
'@type': 'SoftwareApplication',
|
|
116
|
+
name: title,
|
|
117
|
+
description,
|
|
118
|
+
applicationCategory: 'DeveloperApplication',
|
|
119
|
+
operatingSystem: 'Any',
|
|
120
|
+
offers: {
|
|
121
|
+
'@type': 'Offer',
|
|
122
|
+
price: '0',
|
|
123
|
+
priceCurrency: 'EUR',
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export const content: ToolLocaleContent<JwtDecoderUI> = {
|
|
128
|
+
slug,
|
|
129
|
+
title,
|
|
130
|
+
description,
|
|
131
|
+
ui,
|
|
132
|
+
faqTitle: 'JWT decoder FAQ',
|
|
133
|
+
faq,
|
|
134
|
+
bibliographyTitle: 'JWT specifications and security references',
|
|
135
|
+
bibliography,
|
|
136
|
+
howTo,
|
|
137
|
+
schemas: [appSchema, faqSchema, howToSchema],
|
|
138
|
+
seo: [
|
|
139
|
+
{
|
|
140
|
+
type: 'title',
|
|
141
|
+
text: 'Decode JWTs without losing the security context',
|
|
142
|
+
level: 2,
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
type: 'paragraph',
|
|
146
|
+
html: 'A JSON Web Token looks compact, but it often carries the exact detail that explains an authentication failure: the signing algorithm, issuer, audience, subject, issued-at time, not-before time, expiration and application-specific authorization claims. This <strong>JWT decoder, parser and claims inspector</strong> turns the three token segments into readable JSON so you can debug auth flows faster.',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
type: 'diagnostic',
|
|
150
|
+
variant: 'warning',
|
|
151
|
+
title: 'Decoded does not mean trusted',
|
|
152
|
+
html: 'Anyone can base64url-decode a JWT. Trust begins only after your application verifies the signature with the correct secret, public key or JWKS, then validates issuer, audience, expiration and any domain-specific claims. Use this tool to inspect data, not to accept a token as authentic.',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
type: 'title',
|
|
156
|
+
text: 'What each JWT segment tells you',
|
|
157
|
+
level: 3,
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
type: 'table',
|
|
161
|
+
headers: ['Segment', 'Typical content', 'Debugging value'],
|
|
162
|
+
rows: [
|
|
163
|
+
['Header', 'Algorithm, token type and optional key id', 'Shows whether the token expects HS256, RS256, ES256 or another verification strategy.'],
|
|
164
|
+
['Payload', 'Registered claims and application claims', 'Reveals identity, tenant, scopes, roles, expiration and audience mismatches.'],
|
|
165
|
+
['Signature', 'Cryptographic signature bytes encoded as base64url', 'Confirms that a signature segment exists, but must be verified with the right key elsewhere.'],
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
type: 'title',
|
|
170
|
+
text: 'Claims that usually explain broken authentication',
|
|
171
|
+
level: 3,
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
type: 'list',
|
|
175
|
+
items: [
|
|
176
|
+
'<strong>exp:</strong> if the token expired, refresh logic or clock settings may be wrong.',
|
|
177
|
+
'<strong>nbf:</strong> if the token is not active yet, server and identity provider clocks may be out of sync.',
|
|
178
|
+
'<strong>iss:</strong> if the issuer URL differs from configuration, the token may come from the wrong tenant or environment.',
|
|
179
|
+
'<strong>aud:</strong> if the audience does not match the API identifier, the token was minted for another resource.',
|
|
180
|
+
'<strong>alg:</strong> if the algorithm is unexpected, your verifier may reject the token or expose a dangerous configuration mistake.',
|
|
181
|
+
],
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
type: 'title',
|
|
185
|
+
text: 'Use cases for a JWT parser during development',
|
|
186
|
+
level: 3,
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
type: 'comparative',
|
|
190
|
+
columns: 3,
|
|
191
|
+
items: [
|
|
192
|
+
{
|
|
193
|
+
title: 'Frontend debugging',
|
|
194
|
+
description: 'Inspect ID tokens and access tokens received after login to confirm scopes, roles and profile claims.',
|
|
195
|
+
icon: 'mdi:monitor-dashboard',
|
|
196
|
+
points: ['Check profile claims', 'Confirm scopes and roles', 'Compare login environments'],
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
title: 'Backend API QA',
|
|
200
|
+
description: 'Compare expected issuer and audience values with the token actually sent in an Authorization header.',
|
|
201
|
+
icon: 'mdi:api',
|
|
202
|
+
highlight: true,
|
|
203
|
+
points: ['Validate audience shape', 'Spot issuer mismatches', 'Inspect bearer tokens'],
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
title: 'Identity provider setup',
|
|
207
|
+
description: 'Check whether claims from Auth0, Azure AD, Cognito, Keycloak or a custom provider are shaped as your app expects.',
|
|
208
|
+
icon: 'mdi:account-key',
|
|
209
|
+
points: ['Review tenant data', 'Check custom claims', 'Compare provider mappings'],
|
|
210
|
+
},
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
type: 'title',
|
|
215
|
+
text: 'Common JWT mistakes this inspector makes obvious',
|
|
216
|
+
level: 3,
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
type: 'proscons',
|
|
220
|
+
title: 'Fast checks versus trust decisions',
|
|
221
|
+
items: [
|
|
222
|
+
{
|
|
223
|
+
pro: 'See malformed tokens immediately.',
|
|
224
|
+
con: 'It cannot know your expected audience or issuer.',
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
pro: 'Convert Unix timestamp claims into readable dates.',
|
|
228
|
+
con: 'It cannot verify a signature without the real key material.',
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
pro: 'Spot missing issuer, audience, subject or type values.',
|
|
232
|
+
con: 'It cannot prove that scopes and roles are safe for your application.',
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
type: 'summary',
|
|
238
|
+
title: 'Best practice workflow',
|
|
239
|
+
items: [
|
|
240
|
+
'Decode the token to understand what the client or API actually received.',
|
|
241
|
+
'Check exp, nbf, iss, aud, sub and alg before chasing application logic.',
|
|
242
|
+
'Verify signatures and trust decisions only in your auth layer.',
|
|
243
|
+
'Avoid sharing sensitive production JWTs in tickets, logs or screenshots.',
|
|
244
|
+
],
|
|
245
|
+
},
|
|
246
|
+
],
|
|
247
|
+
};
|