You are currently viewing Tutorial JWT: Panduan Praktis Membuat Otentikasi API dengan Node.js & Express

Tutorial JWT: Panduan Praktis Membuat Otentikasi API dengan Node.js & Express

Pada artikel sebelumnya, JWT 101: Kunci Digital Dunia Modern, kita telah membedah anatomi dan konsep di balik JSON Web Token. Kita memahaminya sebagai “gelang VIP” digital yang bekerja secara stateless. Kini, saatnya berhenti berteori dan mulai membangun.

Dalam panduan ini, kita akan membuat sebuah API sederhana menggunakan Node.js dan Express.js. Kita akan mengimplementasikan sistem otentikasi JWT dari nol, lengkap dengan proses pembuatan token saat login dan verifikasi token untuk melindungi endpoint tertentu.

Mari kita mulai!

Prasyarat

Pastikan Anda telah menginstal Node.js dan npm (atau yarn) di mesin Anda. Pemahaman dasar tentang JavaScript dan cara kerja Express.js akan sangat membantu.


Langkah 1: Inisialisasi Proyek dan Instalasi Dependensi

Pertama, buat sebuah direktori baru untuk proyek kita, masuk ke dalamnya, dan inisialisasi proyek Node.js.

mkdir jwt-auth-api
cd jwt-auth-api
npm init -y

Selanjutnya, kita akan menginstal beberapa paket yang kita butuhkan:

  • express: Kerangka kerja web yang akan kita gunakan.
  • jsonwebtoken: Paket utama untuk membuat dan memverifikasi JWT.
  • bcrypt: Untuk mengenkripsi password pengguna secara aman.
  • dotenv: Untuk mengelola variabel lingkungan (seperti kunci rahasia JWT).
npm install express jsonwebtoken bcrypt dotenv

Langkah 2: Struktur Proyek dan Setup Server Dasar

Buat sebuah file bernama index.js. Ini akan menjadi titik masuk utama aplikasi kita.

// index.js
require('dotenv').config();
const express = require('express');

const app = express();
app.use(express.json()); // Middleware untuk mem-parsing body JSON

const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.send('Server Otentikasi JWT berjalan!');
});

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

Selanjutnya, buat file .env di direktori root proyek Anda. Ini adalah tempat kita akan menyimpan kunci rahasia kita.

# .env
JWT_SECRET=iniadalahkuncirahasiayangSANGATpanjangdanrumit12345

Praktik Terbaik (Amanah): Jangan pernah menuliskan kunci rahasia (secret key) langsung di dalam kode. Menggunakan file .env memungkinkan Anda menjaga kerahasiaan kunci ini dan mudah menggantinya tanpa mengubah kode.


Langkah 3: Registrasi dan Login Pengguna

Dalam aplikasi nyata, Anda akan menggunakan database. Untuk kesederhanaan tutorial ini, kita akan menggunakan array sederhana untuk menyimpan data pengguna.

Tambahkan kode berikut di index.js:

// index.js (lanjutan)
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');

// Ganti ini dengan database di aplikasi nyata
const users = [];

// Endpoint untuk registrasi pengguna baru
app.post('/register', async (req, res) => {
  try {
    const { username, password } = req.body;
    
    // Enkripsi password sebelum disimpan
    const hashedPassword = await bcrypt.hash(password, 10);
    
    users.push({ username, password: hashedPassword });
    res.status(201).send('Pengguna berhasil dibuat.');
  } catch {
    res.status(500).send('Terjadi kesalahan pada server.');
  }
});

// Endpoint untuk login dan pembuatan token
app.post('/login', async (req, res) => {
  const { username, password } = req.body;
  const user = users.find(u => u.username === username);

  if (!user) {
    return res.status(400).send('Username atau password salah.');
  }

  try {
    // Bandingkan password yang diinput dengan hash di "database"
    if (await bcrypt.compare(password, user.password)) {
      // Jika cocok, buat JWT
      const payload = { username: user.username };
      const accessToken = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '15m' });
      
      res.json({ accessToken: accessToken });
    } else {
      res.status(400).send('Username atau password salah.');
    }
  } catch {
    res.status(500).send('Terjadi kesalahan pada server.');
  }
});

Di sini, saat login berhasil, kita membuat token menggunakan jwt.sign(). Kita memasukkan payload (informasi yang ingin kita simpan di token), secret key dari .env, dan opsi expiresIn untuk memberikan masa kedaluwarsa pada token.


Langkah 4: Membuat Middleware Verifikasi Token

Sekarang, kita butuh cara untuk memeriksa token pada setiap permintaan ke endpoint yang ingin kita lindungi. Inilah gunanya middleware. Buat fungsi middleware berikut di index.js.

// index.js (lanjutan)

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

  if (token == null) {
    return res.sendStatus(401); // Unauthorized
  }

  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
    if (err) {
      return res.sendStatus(403); // Forbidden (token tidak valid)
    }
    req.user = user;
    next(); // Lanjutkan ke route berikutnya
  });
}

Middleware ini akan:

  1. Mengambil token dari Authorization header.
  2. Memastikan token ada.
  3. Memverifikasi token menggunakan jwt.verify().
  4. Jika valid, informasi pengguna dari payload token akan disimpan di req.user dan permintaan dilanjutkan.
  5. Jika tidak valid, permintaan akan dihentikan dengan status error.

Langkah 5: Melindungi Endpoint

Terakhir, mari kita buat sebuah endpoint yang hanya bisa diakses jika pengguna mengirimkan token yang valid. Kita cukup menempatkan middleware authenticateToken sebelum handler route kita.

// index.js (lanjutan)

// Endpoint yang dilindungi
app.get('/profile', authenticateToken, (req, res) => {
  // req.user berisi payload dari token yang sudah diverifikasi
  res.send(`Selamat datang di halaman profil, ${req.user.username}!`);
});

Sekarang, jika Anda mencoba mengakses /profile tanpa menyertakan Authorization: Bearer <token> yang valid di header, Anda akan mendapatkan error 401 atau 403.

Kesimpulan: Anda Telah Membangunnya!

Selamat! Anda telah berhasil mengimplementasikan alur otentikasi JWT yang lengkap: registrasi dengan password hashing, login yang menghasilkan token, sebuah middleware verifikasi, dan sebuah endpoint yang terlindungi.

Ini adalah fondasi yang sangat kuat. Namun, perjalanan kita belum selesai.

Token yang kita buat memiliki masa berlaku singkat (15 menit). Apa yang terjadi jika token itu kedaluwarsa? Apakah pengguna harus login lagi setiap 15 menit? Tentu tidak praktis. Selain itu, bagaimana cara kita menangani proses logout dengan benar di sistem stateless ini?

Pertanyaan-pertanyaan kritis inilah yang akan kita jawab di artikel pamungkas seri ini, di mana kita akan menyelami topik keamanan tingkat lanjut seperti Refresh Token dan Token Blacklisting.

Baca Selanjutnya > Mengamankan JWT: Panduan Lengkap Refresh Token, Blacklisting, dan Praktik Terbaik

Rama Aditya

Rama Aditya adalah seorang Konsultan Bisnis, Fullstack Developer, dan Maestro Pemasaran Digital dengan pengalaman membangun 30+ prototipe sistem. Saat ini, beliau mendedikasikan keahliannya untuk membantu UMKM dan pebisnis bertransformasi secara digital di atas fondasi prinsip yang amanah. Butuh rekan diskusi untuk bisnis Anda? Kunjungi RamaDigital.id.

Tinggalkan Balasan

Situs ini menggunakan Akismet untuk mengurangi spam. Pelajari bagaimana data komentar Anda diproses