Menu

JWT di Node.js: Sign, Verify dan Melindungi Route Express

JWT adalah token bertanda tangan yang terdiri dari tiga bagian base64url, diterbitkan server saat login dan dicek di setiap request. Di Node.js kamu membuat dan memverifikasinya dengan package jose atau jsonwebtoken dan sebuah secret key.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

JWT (JSON Web Token) adalah string berisi tiga bagian base64url, header.payload.signature, yang diberikan server kepada user saat login dan dicek di setiap request sesudahnya. Signature-nya membuktikan bahwa server yang menerbitkan token dan tidak ada yang mengubahnya, tetapi payload-nya hanya di-encode, tidak dienkripsi, jadi siapa pun bisa membacanya. Di Node.js kamu membuatnya dengan new SignJWT(payload).sign(secret) dari package jose dan mengeceknya dengan jwtVerify(token, secret).

Hasilnya 3 parts, lalu user-42 admin: jwtVerify mengecek signature dan masa berlakunya lalu mengembalikan payload-nya. Ubah satu karakter dari secret yang diberikan ke jwtVerify lalu jalankan lagi: verifikasinya gagal dengan signature verification failed.

Apa isi sebuah JWT

Header dan payload-nya adalah JSON, di-encode dengan base64url. Men-decode-nya tidak butuh key, itulah sebabnya JWT tidak boleh berisi password atau hal rahasia lainnya.

Dua baris pertama mencetak {"alg":"HS256"} dan {"name":"Ada","role":"editor"}, yang bisa dibaca siapa pun yang memegang token-nya. Signature-nya (43 karakter untuk HS256) yang mencegah mereka mengubahnya: ganti editor menjadi admin dan signature-nya tidak cocok lagi.

BagianBerisiRahasia?
HeaderAlgoritmanya, seperti HS256Tidak, bisa dibaca
PayloadClaim: sub (id user), exp (kedaluwarsa), iat (waktu terbit), field milikmu sendiriTidak, bisa dibaca
SignatureSignature HMAC atau RSA dari dua bagian pertamaButuh key untuk membuatnya

Masa berlaku dan verifikasi yang gagal

setExpirationTime('15m') menulis claim exp, dan jwtVerify menolak token yang sudah melewatinya. Setiap penolakan adalah error dengan code, jadi kamu bisa membedakan token yang kedaluwarsa dari token palsu.

Pengecekan pertama gagal dengan ERR_JWT_EXPIRED dan yang kedua, yang signature-nya diubah, dengan ERR_JWS_SIGNATURE_VERIFICATION_FAILED. Bagi API-mu keduanya berarti sama (jawab 401), tetapi mencatat kodenya membantu saat debugging.

Melindungi route Express dengan Bearer token

Client login sekali, menyimpan token-nya, lalu mengirimnya di header Authorization sebagai Bearer <token>. Sebuah middleware memverifikasinya dan menaruh payload-nya di req.user untuk route.

Request pertama, GET /me tanpa token, mendapat 401 dan Missing token. Kirim POST /login dengan body {"username": "ada", "password": "lovelace"}, salin token dari response-nya, lalu kirim GET /me lagi dengan header Authorization: Bearer <token>: jawabannya {"id":"user-1","name":"ada"}.

Package jsonwebtoken

jsonwebtoken (npm install jsonwebtoken) adalah pilihan umum lainnya. sign dan verify miliknya synchronous (dengan callback opsional), bukan mengembalikan promise:

const jwt = require('jsonwebtoken');

const token = jwt.sign({ role: 'admin' }, process.env.JWT_SECRET, {
    subject: 'user-42',
    expiresIn: '1h',
});

const payload = jwt.verify(token, process.env.JWT_SECRET); // throws if invalid

Pakai jose untuk kode baru: package ini tidak punya dependency dan juga berjalan di edge runtime dan browser. Token dari kedua library adalah JWT standar, jadi yang satu bisa memverifikasi token yang ditandatangani yang lain.

Kesalahan umum

Memakai decode alih-alih verify. jwt.decode dan decodeJwt membaca payload tanpa mengecek signature-nya, jadi token palsu bisa lolos. Percayai hanya apa yang dikembalikan verify.

Secret yang pendek atau ikut di-commit. Secret HS256 yang bisa ditebak membuat penyerang bisa menandatangani token mereka sendiri. Pakai paling sedikit 32 byte acak, baca dari process.env, dan jangan pernah commit.

Token yang tidak pernah kedaluwarsa. Tanpa exp, token yang bocor berlaku selamanya. Selalu atur masa berlaku.

Pertanyaan yang sering diajukan

Di mana client sebaiknya menyimpan JWT?

Di aplikasi browser, cookie HttpOnly dan Secure paling aman, karena script halaman tidak bisa membacanya. localStorage lebih sederhana, tetapi script apa pun di halaman itu, termasuk yang disusupkan, bisa membaca token-nya. Aplikasi mobile memakai penyimpanan aman milik platformnya.

Bagaimana cara logout user dengan JWT?

Server tidak bisa membatalkan token yang sudah ditandatanganinya; token itu tetap berlaku sampai kedaluwarsa. Hapus di client, buat access token berumur pendek, dan kalau kamu butuh logout seketika, simpan daftar id token yang dicabut (jti) di server dan cek di setiap request.

HS256 atau RS256?

HS256 memakai satu secret bersama untuk sign dan verify, cocok untuk satu backend. RS256 melakukan sign dengan private key dan verify dengan public key, jadi service lain bisa mengecek token tanpa bisa membuatnya.

Berapa lama JWT sebaiknya berlaku?

Access token biasanya berlaku 5 sampai 60 menit. Untuk sesi yang lebih panjang, pasangkan dengan refresh token yang disimpan lebih hati-hati, yang ditukar client dengan access token baru.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai