Pengetahuan

Panduan Autentikasi dengan JWT (JSON Web Token)

Amankan API Anda! Pelajari panduan lengkap autentikasi dengan JWT (JSON Web Token): cara kerja, kelebihan, kekurangan, dan implementasi dasarnya.

Tata Bicara1 Juli 2025

Dalam pengembangan aplikasi web dan mobile modern, mengamankan endpoint API adalah hal yang sangat penting. Salah satu metode autentikasi paling populer dan efisien saat ini adalah menggunakan JSON Web Token (JWT). JWT menawarkan cara yang stateless untuk memverifikasi identitas pengguna, menjadikannya pilihan ideal untuk arsitektur microservices dan API RESTful.

Panduan ini akan membawa Anda memahami apa itu JWT, bagaimana cara kerjanya, kelebihan dan kekurangannya, serta langkah-langkah dasar untuk mengimplementasikannya dalam aplikasi Anda. Mari kita selami cara kerja JWT dan mengapa ia menjadi pilihan favorit para developer.

Apa Itu JSON Web Token (JWT)?

JWT adalah standar terbuka (RFC 7519) yang mendefinisikan cara aman untuk mentransmisikan informasi antara dua pihak sebagai objek JSON. Informasi ini dapat diverifikasi karena ditandatangani secara digital. JWT sering digunakan untuk autentikasi dan otorisasi.

Sebuah JWT memiliki tiga bagian, dipisahkan oleh titik (.):

  1. Header: Berisi metadata tentang token, seperti tipe token (JWT) dan algoritma hashing yang digunakan untuk tanda tangan (misalnya, HS256, RS256). JSON

    {
      "alg": "HS256",
      "typ": "JWT"
    }
    
  2. Payload (Claims): Berisi klaim (informasi) tentang entitas (biasanya pengguna) dan metadata tambahan. Ada tiga jenis klaim:
    • Registered Claims: Klaim standar yang direkomendasikan tapi tidak wajib (misalnya, iss (issuer), exp (expiration time), sub (subject), aud (audience)).
    • Public Claims: Klaim khusus yang bisa Anda definisikan sendiri, tapi disarankan untuk mendaftarkannya secara publik atau menghindari konflik nama.
    • Private Claims: Klaim kustom yang disepakati antara pengirim dan penerima, tidak standar.
    JSON

    {
      "sub": "1234567890",
      "name": "John Doe",
      "admin": true,
      "iat": 1516239022 // Issued At
    }
    
  3. Signature (Tanda Tangan): Dihasilkan dengan menggabungkan Encoded Header, Encoded Payload, dan sebuah secret key (kunci rahasia) menggunakan algoritma hashing yang ditentukan di Header.
    HMACSHA256(
      base64UrlEncode(header) + "." +
      base64UrlEncode(payload),
      secret
    )
    
    Tanda tangan ini memastikan bahwa token tidak dimanipulasi di tengah jalan. Jika ada bagian dari Header atau Payload yang diubah, tanda tangan tidak akan cocok, dan token akan dianggap tidak valid.

Ketiga bagian ini kemudian di-encode menggunakan Base64Url dan digabungkan dengan titik, menghasilkan string JWT yang kita kenal: xxxxx.yyyyy.zzzzz

Bagaimana Cara Kerja Autentikasi dengan JWT?

Siklus autentikasi dengan JWT biasanya melibatkan langkah-langkah berikut:

  1. Login Pengguna:
    • Pengguna mengirimkan kredensial (misalnya, username dan password) ke server (API backend).
  2. Verifikasi Kredensial:
    • Server memverifikasi kredensial pengguna terhadap database atau sistem autentikasi lainnya.
  3. Pembuatan JWT:
    • Jika kredensial valid, server membuat JWT yang berisi payload (misalnya, ID pengguna, role, waktu kadaluarsa).
    • JWT ini ditandatangani menggunakan secret key yang hanya diketahui oleh server.
  4. Pengiriman JWT ke Klien:
    • Server mengirimkan JWT kembali ke klien (aplikasi frontend atau mobile). JWT ini biasanya disertakan dalam body respons atau sebagai header Authorization.
  5. Penyimpanan JWT di Klien:
    • Klien menyimpan JWT, biasanya di Local Storage, Session Storage, atau cookies (dengan pengaturan HttpOnly untuk keamanan tambahan).
  6. Akses ke Sumber Daya Terlindungi (Authenticated Requests):
    • Setiap kali klien ingin mengakses endpoint API yang dilindungi, klien menyertakan JWT dalam header Authorization sebagai Bearer Token.
    Authorization: Bearer <your_jwt_token_here>
    
  7. Verifikasi JWT di Server:
    • Ketika server menerima permintaan dengan JWT, ia akan:
      • Mengekstrak JWT dari header Authorization.
      • Memverifikasi tanda tangan JWT menggunakan secret key yang sama.
      • Memeriksa apakah token sudah kadaluarsa (exp claim).
      • Jika tanda tangan valid dan token belum kadaluarsa, server menganggap pengguna terautentikasi dan mengizinkan akses ke sumber daya. Informasi dari payload (misalnya, ID pengguna) dapat digunakan untuk otorisasi (menentukan apa yang boleh diakses pengguna).
  8. Logout Pengguna:
    • Ketika pengguna logout, klien cukup menghapus JWT dari penyimpanannya. Tidak ada pembatalan token di sisi server secara default (kecuali diimplementasikan secara manual dengan blacklist).

Kelebihan JWT

  • Stateless: Server tidak perlu menyimpan informasi sesi. Setiap permintaan dari klien berisi semua yang dibutuhkan server untuk memverifikasi identitas. Ini sangat baik untuk skalabilitas karena permintaan dapat diarahkan ke server manapun tanpa khawatir tentang sticky sessions.
  • Keamanan: Tanda tangan digital mencegah manipulasi token. Jika token diubah, server akan mendeteksinya.
  • Portabilitas: JWT dapat digunakan di berbagai platform dan bahasa pemrograman.
  • Compact: Ukurannya relatif kecil, cocok untuk transmisi melalui URL, POST parameter, atau HTTP header.
  • Decentralized Authorization: Informasi otorisasi (misalnya, role pengguna) dapat disertakan dalam payload, memungkinkan microservices yang berbeda untuk memverifikasi otorisasi tanpa perlu menghubungi database pusat setiap kali.

Kekurangan JWT

  • Tidak Ada Pembatalan Token (Revocation) Bawaan: Setelah JWT diterbitkan, server tidak memiliki kontrol langsung untuk membatalkannya sebelum waktu kadaluarsanya. Jika token dicuri, ia tetap valid sampai kadaluarsa. Solusinya memerlukan implementasi blacklist token di sisi server.
  • Ukuran Payload: Meskipun compact, payload yang terlalu besar dapat meningkatkan ukuran header permintaan. Informasi sensitif tidak boleh disimpan di payload karena hanya di-encode, bukan dienkripsi.
  • Keamanan Secret Key: Keamanan JWT sangat bergantung pada kerahasiaan secret key. Jika secret key bocor, penyerang dapat membuat JWT palsu.
  • Refresh Token Complexity: Untuk mengatasi masalah revocation dan masa berlaku yang singkat, sering digunakan kombinasi access token (JWT berumur pendek) dan refresh token (token berumur panjang). Ini menambah kompleksitas implementasi.

Contoh Implementasi Sederhana (Konseptual dengan Node.js/Express.js)

Berikut adalah contoh konseptual bagaimana JWT dapat diimplementasikan menggunakan Node.js dengan Express.js.

1. Instalasi Library

Bash

npm install express jsonwebtoken dotenv

2. Konfigurasi (server.js)

JavaScript

// server.js
const express = require('express');
const jwt = require('jsonwebtoken');
const dotenv = require('dotenv');

dotenv.config(); // Load environment variables from .env file

const app = express();
app.use(express.json()); // For parsing application/json

const PORT = process.env.PORT || 3000;
const JWT_SECRET = process.env.JWT_SECRET || 'your_secret_key'; // Ganti dengan kunci rahasia yang kuat!

// Data pengguna dummy (simulasi database)
const users = [
    { id: 1, username: 'user1', password: 'password1', role: 'user' },
    { id: 2, username: 'admin', password: 'adminpassword', role: 'admin' }
];

// Middleware untuk memverifikasi JWT
function authenticateToken(req, res, next) {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN_ANDA

    if (token == null) return res.sendStatus(401); // Tidak ada token

    jwt.verify(token, JWT_SECRET, (err, user) => {
        if (err) return res.sendStatus(403); // Token tidak valid atau kadaluarsa
        req.user = user; // Menambahkan informasi pengguna dari payload ke objek request
        next(); // Lanjutkan ke route berikutnya
    });
}

// --- Routes ---

// Route Login
app.post('/login', (req, res) => {
    const { username, password } = req.body;
    const user = users.find(u => u.username === username && u.password === password);

    if (user) {
        // Buat JWT
        const accessToken = jwt.sign(
            { id: user.id, username: user.username, role: user.role },
            JWT_SECRET,
            { expiresIn: '1h' } // Token akan kadaluarsa dalam 1 jam
        );
        res.json({ accessToken: accessToken });
    } else {
        res.status(401).json({ message: 'Invalid credentials' });
    }
});

// Route yang dilindungi (hanya bisa diakses dengan JWT valid)
app.get('/protected', authenticateToken, (req, res) => {
    res.json({ message: `Halo, ${req.user.username}! Anda berhasil mengakses resource yang dilindungi.` });
});

// Route yang dilindungi dan membutuhkan role admin
app.get('/admin-only', authenticateToken, (req, res) => {
    if (req.user.role !== 'admin') {
        return res.status(403).json({ message: 'Akses ditolak. Perlu hak akses admin.' });
    }
    res.json({ message: `Selamat datang, Admin ${req.user.username}!` });
});

app.listen(PORT, () => {
    console.log(`Server berjalan di http://localhost:${PORT}`);
});

3. File .env (untuk Kunci Rahasia)

Buat file .env di root proyek Anda:

JWT_SECRET=SUPER_RAHASIA_DAN_PANJANG_DAN_ACAK

Penting: Ganti SUPER_RAHASIA_DAN_PANJANG_DAN_ACAK dengan string yang sangat panjang, acak, dan sulit ditebak. Gunakan tool generator untuk ini. Jangan pernah ekspos kunci ini ke publik!

Peran Refresh Token

Untuk mengatasi kekurangan JWT terkait pembatalan dan masa berlaku singkat, sering digunakan Refresh Token:

  • Access Token (JWT): Berumur pendek (misalnya, 15 menit - 1 jam). Digunakan untuk mengakses resource API yang dilindungi. Jika dicuri, hanya valid untuk waktu singkat.
  • Refresh Token: Berumur panjang (misalnya, 7 hari - 30 hari). Disimpan di database server dan digunakan hanya untuk meminta access token baru ketika access token lama kadaluarsa.
  • Alur:
    1. Pengguna login, server memberikan Access Token dan Refresh Token.
    2. Klien menggunakan Access Token untuk permintaan API.
    3. Ketika Access Token kadaluarsa, klien mengirimkan Refresh Token ke server.
    4. Server memverifikasi Refresh Token terhadap database. Jika valid, server mengeluarkan Access Token baru dan mungkin juga Refresh Token baru.
    5. Jika Refresh Token dicurigai atau dibatalkan, server tidak akan mengeluarkan Access Token baru, memaksa pengguna untuk login ulang.

Efektif dan Scalable

JWT adalah solusi yang efektif dan scalable untuk autentikasi dan otorisasi dalam aplikasi modern. Kemampuannya untuk menyediakan informasi stateless dan dapat diverifikasi membuatnya menjadi pilihan yang sangat baik untuk API RESTful dan arsitektur microservices.

Meskipun memiliki kelebihan dalam skalabilitas dan keamanan integritas data, penting untuk memahami kekurangannya, terutama terkait pembatalan token. Dengan implementasi yang tepat, termasuk pengelolaan secret key yang aman dan pertimbangan penggunaan refresh token, Anda dapat membangun sistem autentikasi yang kuat dan andal menggunakan JWT.

Share:

0 Komentar

Artikel Terkait