Lompat ke konten
Aback Tools Logo

Cara Memvalidasi Konfigurasi JWT di TypeScript: Algoritma, Claim, dan Secret

Cara memvalidasi konfigurasi JWT di TypeScript: menegakkan algoritma di jwt.verify(), memvalidasi claim exp/nbf/iss/aud, rotasi kunci dengan JWKS, dan mendebug token dengan alat berbasis browser.

DH
Tutorials & How-Tos12 menit baca2,750 kata

Sebagian besar bug JWT di TypeScript tidak ada pada token-nya — melainkan pada konfigurasi verifikasinya. Batasan algoritma yang hilang, claim penerbit yang tak diperiksa, atau secret berumur pendek bisa diam-diam merusak autentikasi sedemikian rupa hingga hanya muncul di produksi. Panduan ini menelusuri setiap dimensi ketepatan konfigurasi JWT di TypeScript: algoritma, validasi claim, kebersihan secret, penanganan kedaluwarsa, serta alat berbasis browser yang mempercepat debugging.

3Bagian header JWTheader · payload · tanda tangan
RS256Algoritma yang direkomendasikanAsimetris, aman untuk produksi
0 KBUnggahan ke serverDebugging JWT di browser

Apa yang dicakup validasi konfigurasi JWT

JSON Web Token (JWT) adalah string ringkas yang aman untuk URL, terdiri dari tiga bagian berenkode Base64URL yang dipisah titik: header yang menyatakan algoritma dan jenis token, payload yang membawa claim, dan tanda tangan yang mengikat keduanya. Memvalidasi JWT berarti memastikan ketiga bagian utuh dan claim-nya memenuhi persyaratan aplikasi Anda — bukan sekadar tanda tangannya benar secara matematis.

Dua lapis validasi JWT

Validasi kriptografis mengonfirmasi tanda tangan: server memastikan token ditandatangani dengan kunci yang diharapkan dan tidak dimanipulasi. Validasi konfigurasi melangkah lebih jauh: ia memeriksa bahwa token diterbitkan oleh otoritas yang tepat, ditujukan untuk layanan spesifik ini, belum kedaluwarsa, dan membawa claim kustom yang diharapkan. Sebagian besar kerentanan keamanan JWT berasal dari validasi konfigurasi yang tidak lengkap, bukan dari kriptografi yang rusak.

  • Algoritma (`alg`) - harus sama persis dengan konfigurasi server Anda; jangan pernah menebaknya dari header token
  • Kedaluwarsa (`exp`) - token tidak boleh melewati stempel waktu kedaluwarsanya, dengan memperhitungkan toleransi jam
  • Tidak-sebelum (`nbf`) - token tidak boleh dipakai sebelum waktu valid paling awalnya
  • Penerbit (`iss`) - token harus berasal dari layanan autentikasi tepercaya Anda
  • Audiens (`aud`) - token harus ditujukan untuk API atau layanan spesifik ini
  • Claim kustom - peran, scope, ID tenant, atau field spesifik aplikasi mana pun yang jadi tumpuan logika Anda

Note

Validasi struktur JWT (memeriksa bahwa token adalah string Base64URL tiga bagian yang valid) adalah prasyarat bagi semua validasi lain. [Decoder & Validator JWT](/tools/data/validators/jwt-decoder-and-validator) menanganinya seketika di browser Anda - berguna untuk memastikan token terbentuk baik sebelum menulis kode verifikasi.

Pemeriksaan algoritma dan konfigurasi kunci

Konfigurasi algoritma adalah pengaturan paling kritis dari sisi keamanan dalam verifikasi JWT. Salah menatanya membuka kelas serangan yang melewati autentikasi sepenuhnya. Pustaka JWT TypeScript menyediakan alat untuk menegakkannya dengan benar - tetapi hanya jika Anda memakainya secara eksplisit.

HS256 vs RS256 - memilih algoritma yang tepat

PropertiHS256 (simetris)RS256 (asimetris)
Jenis kunciSecret bersama (kunci sama untuk menandatangani + memverifikasi)Pasangan kunci RSA (privat untuk menandatangani, publik untuk memverifikasi)
Distribusi kunciSetiap verifikator memegang secretHanya penerbit yang memegang kunci privat
Keamanan multi-layanan✗ Berisiko - semua verifikator dapat memalsukan token✓ Verifikator hanya memegang kunci publik
Dukungan OIDC / JWKS✗ Tidak berlaku✓ Kunci publik disajikan lewat endpoint JWKS
Performa✓ Cepat (HMAC)✗ Lebih lambat (matematika RSA)
Paling cocok untukAlat internal, API layanan tunggalAPI produksi, sistem terdistribusi, OIDC

Serangan kebingungan algoritma - dan cara mencegahnya

Kebingungan algoritma terjadi ketika server membaca field `alg` dari header JWT untuk memutuskan cara memverifikasi token, alih-alih menegakkan algoritma dari konfigurasinya sendiri. Penyerang mengubah header dari `RS256` menjadi `HS256`, lalu menandatangani token dengan kunci publik server yang dipakai sebagai secret HMAC. Server yang salah konfigurasi menerimanya sebagai valid. Perbaikannya hanya satu baris kode - tetapi harus ada.

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

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

Warning

Jangan pernah menghilangkan opsi `algorithms` di `jwt.verify()`. Meskipun versi pustaka Anda saat ini menolak algoritma `none` secara default, mencantumkan secara eksplisit algoritma yang diizinkan dalam kode membuat maksudnya jelas, bertahan melewati pembaruan pustaka, dan menghapus sepenuhnya kelas kerentanan kebingungan algoritma.

Validasi kekuatan kunci untuk HS256

Saat memakai HS256, secret harus minimal 256 bit (32 byte) agar sesuai ukuran keluaran SHA-256. Secret pendek - kurang dari 32 karakter, kata kamus, atau string statis seperti `"secret"` atau `"development"` - mudah dipecahkan dengan brute force oleh alat seperti `hashcat` atau `jwt_tool`. Buat secret dengan sumber acak yang aman secara kriptografis: `crypto.randomBytes(32).toString('hex')` di Node.js menghasilkan string heksadesimal 64 karakter yang memenuhi syarat entropi minimum.

Memvalidasi claim JWT standar di TypeScript

Spesifikasi JWT mendefinisikan sejumlah claim terdaftar standar yang harus dipahami setiap implementasi. Pustaka `jsonwebtoken` memvalidasi beberapa di antaranya secara otomatis ketika Anda memberikan opsi yang tepat - tetapi kuncinya pada "ketika Anda memberikannya". Tanpa konfigurasi eksplisit, sebagian besar pemeriksaan claim dilewati diam-diam.

Claim exp, nbf, dan iat

Claim exp (kedaluwarsa) adalah stempel waktu Unix setelah itu token tidak lagi valid. Pustaka jsonwebtoken memeriksa exp secara default selama jwt.verify(). Namun, perbedaan jam antara penerbit token dan verifikator bisa membuat token valid ditolak - penyebab umum kesalahan "token kedaluwarsa" pada sistem terdistribusi yang jam servernya bergeser beberapa detik. Berikan clockTolerance agar ada jendela kecil: menetapkan clockTolerance 30 menerima token hingga 30 detik setelah nilai exp-nya.

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;

Claim iss dan aud

Claim `iss` (penerbit) mengidentifikasi asal token. Claim `aud` (audiens) mengidentifikasi penerima yang dituju. Keduanya opsional dalam spesifikasi JWT tetapi krusial dalam praktik. Tanpa validasi `iss`, layanan mana pun yang mampu menghasilkan token valid dengan kunci penandatanganan Anda dapat mengautentikasi diri ke API Anda. Tanpa validasi `aud`, token yang diterbitkan untuk aplikasi seluler Anda dapat diputar ulang ke API admin Anda. Berikan keduanya sebagai opsi pada `jwt.verify()` agar pustaka menegakkannya sebagai persyaratan ketat, bukan sekadar field informatif.

Tip

Periksa nilai `iss` dan `aud` dari token yang Anda terima dengan menempelkannya ke [Decoder & Validator JWT](/tools/data/validators/jwt-decoder-and-validator). Payload yang didekode menampilkan setiap claim dalam format yang mudah dibaca, memudahkan Anda memastikan string penerbit dan audiens Anda cocok dengan yang diharapkan pustaka.

Mengimplementasikan validasi JWT di TypeScript

Fungsi verifikasi JWT yang lengkap di TypeScript menangani validasi kriptografis, validasi claim, dan klasifikasi kesalahan dalam satu tempat. Begini cara menyusunnya - dengan empat langkah yang sesuai skema HowTo.

1

Pastikan algoritma cocok dengan jenis kunci Anda

Sebelum menulis kode verifikasi apa pun, konfirmasikan kombinasi algoritma dan kunci Anda. RS256 membutuhkan kunci privat RSA untuk menandatangani dan kunci publik terkait untuk memverifikasi. HS256 membutuhkan secret bersama yang sama di kedua sisi. Mencampurnya memicu pengecualian runtime yang sulit didiagnosis. Simpan kunci publik atau secret bersama di variabel lingkungan - jangan pernah meng-hardcode-nya di berkas sumber.

2

Validasi claim exp dan nbf secara eksplisit

Selalu atur `clockTolerance` untuk menangani pergeseran jam kecil antar layanan. Nilai 30 detik adalah default yang wajar untuk sebagian besar sistem terdistribusi. Saat mendebug `TokenExpiredError` di produksi, catat `payload.exp * 1000` dan `Date.now()` bersamaan - ini menunjukkan persis berapa milidetik token melewati kedaluwarsa, membedakan kedaluwarsa nyata dari masalah sinkronisasi jam antara layanan autentikasi dan server API Anda.

3

Periksa claim iss dan aud terhadap nilai yang diharapkan

Berikan opsi `issuer` dan `audience` ke `jwt.verify()` agar pustaka menolak token dengan nilai yang tidak cocok sebelum kode aplikasi Anda berjalan. Jika sistem Anda punya beberapa audiens yang valid (misalnya `api.example.com` dan `admin.example.com`), berikan array: `audience: ['api.example.com', 'admin.example.com']`. Pustaka menerima token jika claim `aud` cocok dengan salah satu entri array.

4

Uji konfigurasi Anda dengan Decoder JWT

Sebelum menjalankan suite pengujian TypeScript, tempelkan contoh token dari lingkungan development atau staging Anda ke Decoder & Validator JWT. Konfirmasikan secara visual bahwa setiap claim - `alg`, `exp`, `iss`, `aud`, dan claim kustom Anda - cocok dengan opsi `jwt.verify()` Anda. Pemeriksaan satu menit ini menangkap ketidaksesuaian antara isi token dan ekspektasi kode Anda sebelum menghabiskan waktu untuk debugging di lingkungan uji.

Decoder & Validator JWT

Dekode token JWT dan periksa semua claim, field header, serta masalah keamanan umum secara instan di browser Anda - tanpa pendaftaran, tanpa unggahan ke server.

Open tool

Kesalahan konfigurasi JWT yang umum

Inilah kesalahan konfigurasi yang paling sering muncul dalam implementasi JWT TypeScript. Masing-masing senyap saat start dan hanya terwujud sebagai kegagalan autentikasi atau insiden keamanan di produksi.

Memakai `jwt.decode()` alih-alih `jwt.verify()`

Fungsi `jwt.decode()` mengekstrak payload tanpa memverifikasi tanda tangan. Ia berguna untuk menginspeksi token yang sudah Anda percayai - misalnya mengekstrak ID pengguna dari token yang telah divalidasi middleware. Ia bukan pengganti `jwt.verify()`. Kode yang memakai `jwt.decode()` untuk memperoleh claim lalu membuat keputusan otorisasi berdasarkan claim tersebut sedang menerima token yang belum terverifikasi. Ini bypass autentikasi total.

Mengabaikan jenis error di blok catch

Pustaka `jsonwebtoken` melempar tiga jenis error berbeda: `JsonWebTokenError` (token cacat atau tanda tangan tidak valid), `TokenExpiredError` (melewati claim `exp`), dan `NotBeforeError` (sebelum claim `nbf`). Menangkap semua error sebagai `Error` generik dan mengembalikan `401 Unauthorized` untuk semua kasus akan menghilangkan informasi diagnostik. Tangani tiap jenis secara terpisah dan kembalikan pesan spesifik - `token kedaluwarsa` versus `token tidak valid` - agar klien dan sistem pemantauan dapat membedakan masalah konfigurasi dari upaya serangan sungguhan.

Tidak merotasi secret atau pasangan kunci

Secret penandatanganan berumur panjang mengumpulkan risiko seiring waktu. Secret yang belum pernah dirotasi berarti setiap token yang pernah diterbitkan dengannya tetap valid bila secret terkompromi. Implementasikan field ID kunci (`kid`) di header JWT Anda agar verifikator dapat mencari kunci publik yang benar dari endpoint JWKS. Pola ini memungkinkan rotasi kunci tanpa membatalkan token yang ditandatangani kunci sebelumnya - setiap token membawa referensi ke kunci spesifik yang menandatanganinya. JWK Inspector membantu memvalidasi keluaran endpoint JWKS dan mendeteksi materi kunci privat yang seharusnya tidak diekspos publik.

Warning

Jangan pernah meng-commit secret JWT atau kunci privat ke kontrol versi. Gunakan variabel lingkungan untuk semua materi kunci, muat saat runtime, dan pastikan sudah terisi sebelum menerima permintaan apa pun. Aplikasi yang berjalan dengan secret tidak terdefinisi atau kosong akan diam-diam menerima token yang ditandatangani string kosong.

Menerima algoritma `none`

Algoritma `none` menghasilkan JWT tanpa tanda tangan - payload apa pun dengan struktur valid lolos verifikasi. Versi pustaka JWT awal menerima `none` secara default. Pustaka modern menolaknya, tetapi hanya ketika Anda secara eksplisit menentukan algoritma yang diizinkan pada opsi verifikasi. Selalu sertakan `algorithms: ['RS256']` (atau algoritma spesifik Anda) agar penolakan `none` menjadi eksplisit dan tahan terhadap perubahan versi pustaka.

Mendebug masalah JWT dengan alat peramban

Menulis tes untuk mereproduksi error JWT sering kali lebih lambat daripada menginspeksi token secara langsung. Alat berbasis browser memungkinkan Anda memeriksa claim, status kedaluwarsa, dan struktur kunci token dalam hitungan detik - tanpa lingkungan lokal, tanpa menjalankan kode, dan tanpa mengunggah data sensitif ke layanan pihak ketiga.

Mendekode dan menginspeksi claim

Decoder & Validator JWT mendekode header dan payload string JWT apa pun serta menyajikan semua claim dalam format terstruktur dan mudah dibaca. Ia memeriksa masalah keamanan umum - `exp` hilang, algoritma lemah, `aud` hilang - dan menandainya dengan diagnostik yang jelas. Tempelkan token dari lingkungan development, staging, atau produksi Anda dan pastikan dalam sepuluh detik apakah claim-nya cocok dengan ekspektasi pemanggilan `jwt.verify()` Anda.

Mendiagnosis masalah kedaluwarsa

Kalkulator Hitung Mundur Kedaluwarsa JWT membaca claim `exp` dari token mana pun dan menampilkan sisa masa pakai persis atau waktu sejak kedaluwarsa baik dalam UTC maupun waktu lokal. Ketika pengguna melaporkan "token kedaluwarsa" tetapi log Anda menunjukkan token seharusnya masih valid, tempelkan ke kalkulator. Perbandingan stempel waktu presisi milidetik mengungkap apakah masalahnya kedaluwarsa sungguhan, pergeseran jam antar layanan, atau nilai `exp` yang tersimpan dalam milidetik alih-alih detik - bug faktor-1000 yang tak kira-kira sering terjadi.

Menginspeksi kumpulan kunci JWKS

Saat memvalidasi token dari penyedia OIDC atau layanan mana pun yang menerbitkan endpoint JWKS, JWK Inspector mengurai dan memvalidasi struktur kumpulan kunci. Ia memastikan setiap kunci memiliki field wajib (`kty`, `use`, `alg`, `kid`), memvalidasi jenis kunci dan kurva untuk kunci EC, serta menandai materi kunci privat yang seharusnya tidak diekspos publik. Tempelkan JSON dari endpoint JWKS Anda langsung ke alat ini atau berikan URL untuk diambil.

Kalkulator Hitung Mundur Kedaluwarsa JWT

Hitung mundur kedaluwarsa JWT secara persis dari claim exp - lihat sisa waktu atau waktu sejak kedaluwarsa dalam UTC dan waktu lokal, tanpa kode.

Open tool

Praktik terbaik validasi JWT

Fungsi verifikasi JWT yang dikonfigurasi dengan benar memang diperlukan, tetapi belum cukup untuk autentikasi yang aman. Praktik-praktik berikut melengkapi gambaran untuk layanan TypeScript produksi.

Gunakan antarmuka payload bertipe

Definisikan antarmuka TypeScript untuk payload JWT Anda dan lakukan cast hasil verifikasi ke antarmuka itu. Ini memberi keamanan saat kompilasi atas nama claim dan jenis nilai - nama claim salah tulis (`userId` vs `user_id`) menjadi kesalahan TypeScript alih-alih `undefined` senyap saat runtime. Simpan antarmuka di modul tipe bersama agar konsisten di semua layanan yang memverifikasi format token yang sama.

Umur token pendek dengan refresh token

Token akses sebaiknya berumur pendek - 15 menit sampai 1 jam untuk sebagian besar API. Token akses berumur panjang (hari, minggu) memperluas jendela ketika token yang terkompromi masih bisa dipakai. Gunakan alur refresh token terpisah dengan kedaluwarsa panjang untuk persistensi sesi. Refresh token dirotasi setiap pemakaian, dan daftar pencabutan hanya diperlukan untuk refresh token - bukan token akses - selama umurnya dijaga pendek.

Sentralisasi logika verifikasi

Tulis verifikasi JWT di satu tempat - fungsi middleware atau utilitas bersama - dan gunakan di mana-mana. Logika verifikasi yang terduplikasi mengundang penyimpangan konfigurasi: satu endpoint memeriksa `aud`, yang lain lupa, dan inkonsistensinya dieksploitasi sebelum ada yang sadar. Middleware Express, guard NestJS, dan route handler Next.js semuanya punya pola rapi untuk mensentralisasi pemeriksaan autentikasi. Letakkan opsi `algorithms`, `issuer`, dan `audience` Anda dalam satu objek konfigurasi yang diimpor di seluruh codebase.

Konfigurasikan verifikasi sekali, tegakkan di mana-mana. Satu-satunya opsi JWT yang boleh berbeda antar endpoint adalah audiens yang diharapkan.

- Prinsip implementasi JWT yang aman

Tip

Saat mengadopsi penyedia autentikasi baru atau memperbarui pustaka JWT, gunakan [Decoder & Validator JWT](/tools/data/validators/jwt-decoder-and-validator) untuk menginspeksi token dari sumber baru sebelum memperbarui konfigurasi verifikasi Anda. Ini mengonfirmasi nilai persis `alg`, `iss`, dan `aud` pada token baru sehingga perubahan kode Anda sesuai kenyataan - bukan asumsi.

Key takeaways

  • Selalu berikan `algorithms: ['RS256']` (atau algoritma spesifik Anda) secara eksplisit ke `jwt.verify()` - jangan biarkan pustaka menebaknya dari header token.
  • Validasi claim `iss` dan `aud` di setiap pemanggilan verifikasi; menghilangkannya memungkinkan token dari layanan lain mengautentikasi ke API Anda.
  • Gunakan `clockTolerance` untuk menangani pergeseran jam antar layanan terdistribusi, dan catat stempel waktu `exp` bersama `Date.now()` saat mendebug kesalahan kedaluwarsa.
  • Jangan pernah memakai `jwt.decode()` untuk keputusan otorisasi - ia melewatkan verifikasi tanda tangan sepenuhnya dan menerima payload token apa pun.
  • Decoder & Validator JWT memungkinkan Anda menginspeksi semua claim dan menandai masalah konfigurasi dalam hitungan detik, tanpa menulis atau menjalankan kode.
  • RS256 lebih disarankan daripada HS256 untuk API produksi - menghilangkan risiko distribusi secret bersama dan mendukung rotasi kunci berbasis JWKS.
  • Jaga umur token akses tetap pendek (15-60 menit) dan sentralisasi seluruh logika verifikasi dalam satu middleware atau utilitas untuk mencegah penyimpangan konfigurasi.

Pertanyaan yang sering diajukan

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