@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 = 'decoder-jwt-parser-dan-inspektur-klaim';
|
|
7
|
+
const title = 'Decoder JWT, Parser dan Inspektur Klaim';
|
|
8
|
+
const description = 'Tempelkan JSON Web Token, dekode header dan payload secara instan, periksa klaim terdaftar, temukan token yang sudah kedaluwarsa, dan salin JSON bersih untuk men-debug alur autentikasi.';
|
|
9
|
+
|
|
10
|
+
const howTo = [
|
|
11
|
+
{
|
|
12
|
+
name: 'Tempelkan JWT',
|
|
13
|
+
text: 'Salin token dari header Authorization, cookie, entri log, atau penyedia identitas dan tempelkan ke kolom input.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'Baca header dan payload yang telah didekode',
|
|
17
|
+
text: 'Alat ini memisahkan token menjadi header, payload, dan tanda tangan, lalu menampilkan segmen JSON di panel terpisah untuk pemeriksaan cepat.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'Periksa klaim penting',
|
|
21
|
+
text: 'Tinjau algoritma, penerbit, audiens, subjek, waktu penerbitan, waktu tidak sebelum, dan waktu kedaluwarsa tanpa mengonversi timestamp Unix secara manual.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Salin data yang Anda butuhkan',
|
|
25
|
+
text: 'Salin satu bagian yang didekode atau keluaran yang didekode lengkap saat Anda perlu membagikan cuplikan debugging yang sudah dibersihkan dengan tim Anda.',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const faq = [
|
|
30
|
+
{
|
|
31
|
+
question: 'Apakah mendekode JWT membuktikan bahwa token tersebut valid?',
|
|
32
|
+
answer: 'Tidak. Dekode hanya mengungkap header dan payload yang dikode base64url. Token hanya dapat dipercaya setelah tanda tangan, penerbit, audiens, kedaluwarsa, dan klaim terkait divalidasi oleh aplikasi atau penyedia identitas.',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
question: 'Bisakah saya menggunakan decoder JWT ini untuk access token dan ID token?',
|
|
36
|
+
answer: 'Ya. Decoder ini berguna untuk memeriksa access token OAuth, ID token OpenID Connect, token sesi, dan token layanan ke layanan, selama menggunakan format JWT tiga bagian standar.',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
question: 'Mengapa panel tanda tangan tidak memverifikasi token?',
|
|
40
|
+
answer: 'Verifikasi JWT memerlukan secret, kunci publik, atau konfigurasi JWKS yang benar. Alat ini sengaja berfokus pada dekode dan inspeksi sehingga pengembang dapat melihat isi token tanpa berpura pura bahwa string tanda tangan yang terlihat adalah bukti validitas.',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
question: 'Apa yang harus saya periksa terlebih dahulu saat men-debug JWT?',
|
|
44
|
+
answer: 'Mulai dengan exp, nbf, iss, aud, dan alg. Sebagian besar masalah produksi nyata berasal dari token yang sudah kedaluwarsa, selisih jam, nilai audiens yang salah, URL penerbit yang tidak terduga, atau asumsi algoritma yang tidak aman.',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
const ui: JwtDecoderUI = {
|
|
49
|
+
tokenLabel: 'Token JWT',
|
|
50
|
+
tokenPlaceholder: 'Tempelkan JWT di sini: header.payload.tanda tangan',
|
|
51
|
+
sampleButton: 'Muat contoh',
|
|
52
|
+
clearButton: 'Bersihkan',
|
|
53
|
+
statusWaiting: 'Tempelkan token untuk mendekode header JSON, payload, dan klaim.',
|
|
54
|
+
statusValid: 'JWT berhasil didekode.',
|
|
55
|
+
statusInvalid: 'Ini tidak terlihat seperti JWT tiga bagian yang valid.',
|
|
56
|
+
statusExpired: 'JWT didekode, tetapi klaim exp sudah kedaluwarsa.',
|
|
57
|
+
statusUnsigned: 'JWT didekode, tetapi tidak ditandatangani atau menggunakan algoritma none.',
|
|
58
|
+
headerTitle: 'Header',
|
|
59
|
+
payloadTitle: 'Payload',
|
|
60
|
+
signatureTitle: 'Tanda tangan',
|
|
61
|
+
claimsTitle: 'Klaim terdaftar',
|
|
62
|
+
copyHeader: 'Salin header yang didekode',
|
|
63
|
+
copyPayload: 'Salin payload yang didekode',
|
|
64
|
+
copySignature: 'Salin tanda tangan',
|
|
65
|
+
copyAll: 'Salin semua',
|
|
66
|
+
copiedLabel: 'Tersalin',
|
|
67
|
+
invalidTokenTitle: 'JWT tidak valid',
|
|
68
|
+
invalidTokenBody: 'Periksa apakah token memiliki tiga segmen base64url yang dipisahkan oleh titik.',
|
|
69
|
+
invalidSegmentError: 'Periksa apakah token memiliki tiga segmen base64url yang dipisahkan oleh titik.',
|
|
70
|
+
invalidDecodeError: 'Header atau payload tidak dapat didekode sebagai JSON yang valid.',
|
|
71
|
+
emptyJson: '{}',
|
|
72
|
+
signaturePresent: 'Segmen tanda tangan ada; verifikasi di lapisan autentikasi Anda dengan kunci yang benar.',
|
|
73
|
+
signatureMissing: 'Tidak ada segmen tanda tangan',
|
|
74
|
+
algorithmLabel: 'Algoritma',
|
|
75
|
+
typeLabel: 'Tipe',
|
|
76
|
+
issuerLabel: 'Penerbit',
|
|
77
|
+
subjectLabel: 'Subjek',
|
|
78
|
+
audienceLabel: 'Audiens',
|
|
79
|
+
issuedAtLabel: 'Diterbitkan pada',
|
|
80
|
+
notBeforeLabel: 'Tidak sebelum',
|
|
81
|
+
expiresAtLabel: 'Kedaluwarsa pada',
|
|
82
|
+
claimMissing: 'Tidak ada',
|
|
83
|
+
privacyNote: 'Dekode berjalan di sesi browser Anda. Jangan tempelkan secret produksi ke alat apa pun kecuali kebijakan keamanan Anda mengizinkannya.',
|
|
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: 'id',
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export const content: ToolLocaleContent<JwtDecoderUI> = {
|
|
129
|
+
slug,
|
|
130
|
+
title,
|
|
131
|
+
description,
|
|
132
|
+
ui,
|
|
133
|
+
faqTitle: 'FAQ decoder JWT',
|
|
134
|
+
faq,
|
|
135
|
+
bibliographyTitle: 'Spesifikasi JWT dan referensi keamanan',
|
|
136
|
+
bibliography,
|
|
137
|
+
howTo,
|
|
138
|
+
schemas: [appSchema, faqSchema, howToSchema],
|
|
139
|
+
seo: [
|
|
140
|
+
{
|
|
141
|
+
type: 'title',
|
|
142
|
+
text: 'Dekode JWT tanpa kehilangan konteks keamanan',
|
|
143
|
+
level: 2,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
type: 'paragraph',
|
|
147
|
+
html: 'JSON Web Token terlihat ringkas, tetapi sering kali membawa detail tepat yang menjelaskan kegagalan autentikasi: algoritma penandatanganan, penerbit, audiens, subjek, waktu penerbitan, waktu tidak sebelum, kedaluwarsa, dan klaim otorisasi khusus aplikasi. <strong>Decoder JWT, parser dan inspektur klaim</strong> ini mengubah tiga segmen token menjadi JSON yang dapat dibaca sehingga Anda dapat men-debug alur autentikasi lebih cepat.',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'diagnostic',
|
|
151
|
+
variant: 'warning',
|
|
152
|
+
title: 'Didekode bukan berarti terpercaya',
|
|
153
|
+
html: 'Siapa pun dapat mendekode JWT dengan base64url. Kepercayaan dimulai hanya setelah aplikasi Anda memverifikasi tanda tangan dengan secret, kunci publik, atau JWKS yang benar, lalu memvalidasi penerbit, audiens, kedaluwarsa, dan klaim khusus domain apa pun. Gunakan alat ini untuk memeriksa data, bukan untuk menerima token sebagai autentik.',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
type: 'title',
|
|
157
|
+
text: 'Apa yang diungkapkan setiap segmen JWT',
|
|
158
|
+
level: 3,
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: 'table',
|
|
162
|
+
headers: ['Segmen', 'Konten umum', 'Nilai debugging'],
|
|
163
|
+
rows: [
|
|
164
|
+
['Header', 'Algoritma, tipe token, dan ID kunci opsional', 'Menunjukkan apakah token mengharapkan HS256, RS256, ES256, atau strategi verifikasi lainnya.'],
|
|
165
|
+
['Payload', 'Klaim terdaftar dan klaim aplikasi', 'Mengungkap identitas, tenant, scope, peran, kedaluwarsa, dan ketidakcocokan audiens.'],
|
|
166
|
+
['Tanda tangan', 'Byte tanda tangan kriptografis yang dikode sebagai base64url', 'Mengonfirmasi bahwa segmen tanda tangan ada, tetapi harus diverifikasi dengan kunci yang benar di tempat lain.'],
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
type: 'title',
|
|
171
|
+
text: 'Klaim yang biasanya menjelaskan kegagalan autentikasi',
|
|
172
|
+
level: 3,
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
type: 'list',
|
|
176
|
+
items: [
|
|
177
|
+
'<strong>exp:</strong> jika token sudah kedaluwarsa, logika refresh atau pengaturan jam mungkin salah.',
|
|
178
|
+
'<strong>nbf:</strong> jika token belum aktif, jam server dan penyedia identitas mungkin tidak sinkron.',
|
|
179
|
+
'<strong>iss:</strong> jika URL penerbit berbeda dari konfigurasi, token mungkin berasal dari tenant atau environment yang salah.',
|
|
180
|
+
'<strong>aud:</strong> jika audiens tidak cocok dengan pengenal API, token diterbitkan untuk sumber daya lain.',
|
|
181
|
+
'<strong>alg:</strong> jika algoritma tidak terduga, verifikator Anda mungkin menolak token atau mengekspos kesalahan konfigurasi yang berbahaya.',
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
type: 'title',
|
|
186
|
+
text: 'Kasus penggunaan parser JWT selama pengembangan',
|
|
187
|
+
level: 3,
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
type: 'comparative',
|
|
191
|
+
columns: 3,
|
|
192
|
+
items: [
|
|
193
|
+
{
|
|
194
|
+
title: 'Debugging frontend',
|
|
195
|
+
description: 'Periksa ID token dan access token yang diterima setelah login untuk mengonfirmasi scope, peran, dan klaim profil.',
|
|
196
|
+
icon: 'mdi:monitor-dashboard',
|
|
197
|
+
points: ['Periksa klaim profil', 'Konfirmasi scope dan peran', 'Bandingkan environment login'],
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
title: 'QA API backend',
|
|
201
|
+
description: 'Bandingkan nilai penerbit dan audiens yang diharapkan dengan token yang sebenarnya dikirim di header Authorization.',
|
|
202
|
+
icon: 'mdi:api',
|
|
203
|
+
highlight: true,
|
|
204
|
+
points: ['Validasi bentuk audiens', 'Temukan ketidakcocokan penerbit', 'Periksa bearer token'],
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
title: 'Pengaturan penyedia identitas',
|
|
208
|
+
description: 'Periksa apakah klaim dari Auth0, Azure AD, Cognito, Keycloak, atau penyedia kustom dibentuk seperti yang diharapkan aplikasi Anda.',
|
|
209
|
+
icon: 'mdi:account-key',
|
|
210
|
+
points: ['Tinjau data tenant', 'Periksa klaim kustom', 'Bandingkan pemetaan penyedia'],
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
type: 'title',
|
|
216
|
+
text: 'Kesalahan JWT umum yang dibuat jelas oleh inspektur ini',
|
|
217
|
+
level: 3,
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
type: 'proscons',
|
|
221
|
+
title: 'Pemeriksaan cepat versus keputusan kepercayaan',
|
|
222
|
+
items: [
|
|
223
|
+
{
|
|
224
|
+
pro: 'Lihat token yang salah format secara langsung.',
|
|
225
|
+
con: 'Tidak dapat mengetahui audiens atau penerbit yang Anda harapkan.',
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
pro: 'Konversi klaim timestamp Unix menjadi tanggal yang dapat dibaca.',
|
|
229
|
+
con: 'Tidak dapat memverifikasi tanda tangan tanpa materi kunci asli.',
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
pro: 'Temukan nilai penerbit, audiens, subjek, atau tipe yang hilang.',
|
|
233
|
+
con: 'Tidak dapat membuktikan bahwa scope dan peran aman untuk aplikasi Anda.',
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
type: 'summary',
|
|
239
|
+
title: 'Alur kerja praktik terbaik',
|
|
240
|
+
items: [
|
|
241
|
+
'Dekode token untuk memahami apa yang sebenarnya diterima oleh klien atau API.',
|
|
242
|
+
'Periksa exp, nbf, iss, aud, sub, dan alg sebelum mengejar logika aplikasi.',
|
|
243
|
+
'Verifikasi tanda tangan dan keputusan kepercayaan hanya di lapisan autentikasi Anda.',
|
|
244
|
+
'Hindari membagikan JWT produksi yang sensitif di tiket, log, atau tangkapan layar.',
|
|
245
|
+
],
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
};
|
|
@@ -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 = 'decodificatore-jwt-parser-e-ispettore-di-claims';
|
|
7
|
+
const title = 'Decodificatore JWT, Parser e Ispettore di Claims';
|
|
8
|
+
const description = 'Incolla un JSON Web Token, decodifica header e payload all\'istante, ispeziona i claims registrati, individua i token scaduti e copia JSON pulito per il debug dei flussi di autenticazione.';
|
|
9
|
+
|
|
10
|
+
const howTo = [
|
|
11
|
+
{
|
|
12
|
+
name: 'Incolla il JWT',
|
|
13
|
+
text: 'Copia un token da un header Authorization, cookie, voce di log o provider di identità e incollalo nel campo di input.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'Leggi header e payload decodificati',
|
|
17
|
+
text: 'Lo strumento divide il token in header, payload e firma, quindi visualizza i segmenti JSON in pannelli separati per un\'ispezione rapida.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'Controlla i claims importanti',
|
|
21
|
+
text: 'Esamina algoritmo, emittente, audience, soggetto, data di emissione, data di inizio validità e data di scadenza senza convertire manualmente i timestamp Unix.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Copia i dati che ti servono',
|
|
25
|
+
text: 'Copia una sezione decodificata o l\'intero output decodificato quando devi condividere un\'istantanea di debug pulita con il tuo team.',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const faq = [
|
|
30
|
+
{
|
|
31
|
+
question: 'Decodificare un JWT dimostra che il token è valido?',
|
|
32
|
+
answer: 'No. La decodifica rivela solo l\'header e il payload codificati in base64url. Un token è affidabile solo dopo che la firma, l\'emittente, l\'audience, la scadenza e i claims correlati sono stati convalidati dall\'applicazione o dal provider di identità.',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
question: 'Posso usare questo decodificatore JWT per access token e ID token?',
|
|
36
|
+
answer: 'Sì. Il decodificatore è utile per ispezionare access token OAuth, ID token OpenID Connect, token di sessione e token da servizio a servizio, purché utilizzino il formato JWT standard in tre parti.',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
question: 'Perché il pannello della firma non verifica il token?',
|
|
40
|
+
answer: 'La verifica JWT richiede il segreto corretto, la chiave pubblica o la configurazione JWKS. Questo strumento si concentra intenzionalmente sulla decodifica e sull\'ispezione, così che gli sviluppatori possano vedere il contenuto del token senza fingere che una stringa di firma visibile sia una prova di validità.',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
question: 'Cosa dovrei controllare per primo quando faccio debug di un JWT?',
|
|
44
|
+
answer: 'Inizia con exp, nbf, iss, aud e alg. La maggior parte dei problemi reali in produzione deriva da token scaduti, sfasamento dell\'orologio, valori di audience errati, URL dell\'emittente inaspettati o ipotesi di algoritmo non sicure.',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
const ui: JwtDecoderUI = {
|
|
49
|
+
tokenLabel: 'Token JWT',
|
|
50
|
+
tokenPlaceholder: 'Incolla un JWT qui: header.payload.firma',
|
|
51
|
+
sampleButton: 'Carica esempio',
|
|
52
|
+
clearButton: 'Cancella',
|
|
53
|
+
statusWaiting: 'Incolla un token per decodificare il suo header JSON, payload e claims.',
|
|
54
|
+
statusValid: 'JWT decodificato con successo.',
|
|
55
|
+
statusInvalid: 'Questo non sembra un JWT valido in tre parti.',
|
|
56
|
+
statusExpired: 'JWT decodificato, ma il claim exp è già scaduto.',
|
|
57
|
+
statusUnsigned: 'JWT decodificato, ma non è firmato o utilizza l\'algoritmo none.',
|
|
58
|
+
headerTitle: 'Header',
|
|
59
|
+
payloadTitle: 'Payload',
|
|
60
|
+
signatureTitle: 'Firma',
|
|
61
|
+
claimsTitle: 'Claims registrati',
|
|
62
|
+
copyHeader: 'Copia header decodificato',
|
|
63
|
+
copyPayload: 'Copia payload decodificato',
|
|
64
|
+
copySignature: 'Copia firma',
|
|
65
|
+
copyAll: 'Copia tutto',
|
|
66
|
+
copiedLabel: 'Copiato',
|
|
67
|
+
invalidTokenTitle: 'JWT non valido',
|
|
68
|
+
invalidTokenBody: 'Verifica che il token abbia tre segmenti base64url separati da punti.',
|
|
69
|
+
invalidSegmentError: 'Verifica che il token abbia tre segmenti base64url separati da punti.',
|
|
70
|
+
invalidDecodeError: 'L\'header o il payload non hanno potuto essere decodificati come JSON valido.',
|
|
71
|
+
emptyJson: '{}',
|
|
72
|
+
signaturePresent: 'Il segmento della firma è presente; verificalo nel tuo livello di autenticazione con la chiave corretta.',
|
|
73
|
+
signatureMissing: 'Nessun segmento di firma',
|
|
74
|
+
algorithmLabel: 'Algoritmo',
|
|
75
|
+
typeLabel: 'Tipo',
|
|
76
|
+
issuerLabel: 'Emittente',
|
|
77
|
+
subjectLabel: 'Soggetto',
|
|
78
|
+
audienceLabel: 'Audience',
|
|
79
|
+
issuedAtLabel: 'Emesso il',
|
|
80
|
+
notBeforeLabel: 'Valido dal',
|
|
81
|
+
expiresAtLabel: 'Scade il',
|
|
82
|
+
claimMissing: 'Non presente',
|
|
83
|
+
privacyNote: 'La decodifica viene eseguita nella sessione del browser. Non incollare segreti di produzione in nessuno strumento, a meno che la tua politica di sicurezza non lo consenta.',
|
|
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: 'it',
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export const content: ToolLocaleContent<JwtDecoderUI> = {
|
|
129
|
+
slug,
|
|
130
|
+
title,
|
|
131
|
+
description,
|
|
132
|
+
ui,
|
|
133
|
+
faqTitle: 'Domande frequenti sul decodificatore JWT',
|
|
134
|
+
faq,
|
|
135
|
+
bibliographyTitle: 'Specifiche JWT e riferimenti di sicurezza',
|
|
136
|
+
bibliography,
|
|
137
|
+
howTo,
|
|
138
|
+
schemas: [appSchema, faqSchema, howToSchema],
|
|
139
|
+
seo: [
|
|
140
|
+
{
|
|
141
|
+
type: 'title',
|
|
142
|
+
text: 'Decodifica i JWT senza perdere il contesto di sicurezza',
|
|
143
|
+
level: 2,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
type: 'paragraph',
|
|
147
|
+
html: 'Un JSON Web Token sembra compatto, ma spesso contiene il dettaglio esatto che spiega un errore di autenticazione: l\'algoritmo di firma, l\'emittente, l\'audience, il soggetto, la data di emissione, la data di inizio validità, la scadenza e i claims di autorizzazione specifici dell\'applicazione. Questo <strong>decodificatore JWT, parser e ispettore di claims</strong> trasforma i tre segmenti del token in JSON leggibile per aiutarti a fare debug dei flussi di autenticazione più velocemente.',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
type: 'diagnostic',
|
|
151
|
+
variant: 'warning',
|
|
152
|
+
title: 'Decodificato non significa affidabile',
|
|
153
|
+
html: 'Chiunque può decodificare un JWT in base64url. La fiducia inizia solo dopo che la tua applicazione ha verificato la firma con il segreto, la chiave pubblica o il JWKS corretti, e poi ha convalidato emittente, audience, scadenza ed eventuali claims specifici del dominio. Usa questo strumento per ispezionare i dati, non per accettare un token come autentico.',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
type: 'title',
|
|
157
|
+
text: 'Cosa ti dice ogni segmento JWT',
|
|
158
|
+
level: 3,
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: 'table',
|
|
162
|
+
headers: ['Segmento', 'Contenuto tipico', 'Valore di debug'],
|
|
163
|
+
rows: [
|
|
164
|
+
['Header', 'Algoritmo, tipo di token e ID chiave opzionale', 'Mostra se il token prevede HS256, RS256, ES256 o un\'altra strategia di verifica.'],
|
|
165
|
+
['Payload', 'Claims registrati e claims applicativi', 'Rivela identità, tenant, scope, ruoli, scadenza e disallineamenti di audience.'],
|
|
166
|
+
['Firma', 'Byte della firma crittografica codificati come base64url', 'Conferma che esiste un segmento di firma, ma deve essere verificato con la chiave corretta altrove.'],
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
type: 'title',
|
|
171
|
+
text: 'Claims che di solito spiegano gli errori di autenticazione',
|
|
172
|
+
level: 3,
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
type: 'list',
|
|
176
|
+
items: [
|
|
177
|
+
'<strong>exp:</strong> se il token è scaduto, la logica di refresh o le impostazioni dell\'orologio potrebbero essere errate.',
|
|
178
|
+
'<strong>nbf:</strong> se il token non è ancora attivo, gli orologi del server e del provider di identità potrebbero non essere sincronizzati.',
|
|
179
|
+
'<strong>iss:</strong> se l\'URL dell\'emittente differisce dalla configurazione, il token potrebbe provenire dal tenant o dall\'ambiente sbagliato.',
|
|
180
|
+
'<strong>aud:</strong> se l\'audience non corrisponde all\'identificatore dell\'API, il token è stato emesso per un\'altra risorsa.',
|
|
181
|
+
'<strong>alg:</strong> se l\'algoritmo è inaspettato, il tuo verificatore potrebbe rifiutare il token o esporre un pericoloso errore di configurazione.',
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
type: 'title',
|
|
186
|
+
text: 'Casi d\'uso di un parser JWT durante lo sviluppo',
|
|
187
|
+
level: 3,
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
type: 'comparative',
|
|
191
|
+
columns: 3,
|
|
192
|
+
items: [
|
|
193
|
+
{
|
|
194
|
+
title: 'Debug frontend',
|
|
195
|
+
description: 'Ispeziona gli ID token e gli access token ricevuti dopo il login per confermare scope, ruoli e claims del profilo.',
|
|
196
|
+
icon: 'mdi:monitor-dashboard',
|
|
197
|
+
points: ['Controlla i claims del profilo', 'Conferma scope e ruoli', 'Confronta gli ambienti di login'],
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
title: 'QA API backend',
|
|
201
|
+
description: 'Confronta i valori attesi di emittente e audience con il token effettivamente inviato in un header Authorization.',
|
|
202
|
+
icon: 'mdi:api',
|
|
203
|
+
highlight: true,
|
|
204
|
+
points: ['Convalida la forma dell\'audience', 'Individua disallineamenti dell\'emittente', 'Ispeziona i bearer token'],
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
title: 'Configurazione del provider di identità',
|
|
208
|
+
description: 'Verifica se i claims di Auth0, Azure AD, Cognito, Keycloak o di un provider personalizzato sono strutturati come la tua app si aspetta.',
|
|
209
|
+
icon: 'mdi:account-key',
|
|
210
|
+
points: ['Esamina i dati del tenant', 'Controlla i claims personalizzati', 'Confronta i mapping del provider'],
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
type: 'title',
|
|
216
|
+
text: 'Errori JWT comuni che questo ispettore rende evidenti',
|
|
217
|
+
level: 3,
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
type: 'proscons',
|
|
221
|
+
title: 'Verifiche rapide contro decisioni di fiducia',
|
|
222
|
+
items: [
|
|
223
|
+
{
|
|
224
|
+
pro: 'Vedi immediatamente i token malformati.',
|
|
225
|
+
con: 'Non può conoscere l\'audience o l\'emittente che ti aspetti.',
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
pro: 'Converti i claims timestamp Unix in date leggibili.',
|
|
229
|
+
con: 'Non può verificare una firma senza il materiale della chiave reale.',
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
pro: 'Individua valori mancanti di emittente, audience, soggetto o tipo.',
|
|
233
|
+
con: 'Non può dimostrare che scope e ruoli sono sicuri per la tua applicazione.',
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
type: 'summary',
|
|
239
|
+
title: 'Flusso di lavoro consigliato',
|
|
240
|
+
items: [
|
|
241
|
+
'Decodifica il token per capire cosa ha effettivamente ricevuto il client o l\'API.',
|
|
242
|
+
'Controlla exp, nbf, iss, aud, sub e alg prima di inseguire la logica applicativa.',
|
|
243
|
+
'Verifica le firme e le decisioni di fiducia solo nel tuo livello di autenticazione.',
|
|
244
|
+
'Evita di condividere JWT di produzione sensibili in ticket, log o screenshot.',
|
|
245
|
+
],
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
};
|