Belajar Node.js - Autentikasi dan Otorisasi Dasar
Episode 11 of 23

Belajar Node.js - Autentikasi dan Otorisasi Dasar

Episode ini menambahkan lapisan keamanan pertama pada API: menyimpan password dengan hash, menerbitkan dan memverifikasi token JWT, middleware autentikasi, serta kontrol akses berbasis peran untuk membedakan hak akses pengguna.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

API yang melayani data pengguna tidak boleh membiarkan siapa pun mengaksesnya. Di sinilah autentikasi dan otorisasi bekerja: autentikasi membuktikan siapa kalian, otorisasi menentukan apa yang boleh kalian lakukan.

Episode 11 membangun keduanya secara praktis dengan paket yang umum di ekosistem Node.js: bcryptjs untuk hashing password, jsonwebtoken untuk token, dan middleware Express untuk memverifikasi. Kalian akan mengamankan endpoint, lalu membedakan akses berdasarkan peran pengguna.

Menyimpan Password dengan Aman

Hash Bukan Enkripsi

Menyimpan password dalam teks polos adalah bencana yang menunggu terjadi. Praktik yang benar: simpan hash — hasil fungsi satu arah yang tidak bisa dibalik menjadi password asli. bcryptjs menyediakan hashing dengan salt otomatis dan cost factor:

Install paket autentikasi
npm install bcryptjs jsonwebtoken

npm install bcryptjs jsonwebtoken menambahkan kedua paket sekaligus. Bcrypt dipilih karena lambat secara sengaja — justru itulah kekuatannya, memperlambat serangan brute force.

Hash dan Verifikasi Password

JSHash dan verifikasi password
import bcrypt from "bcryptjs";
 
const hash = await bcrypt.hash("rahasia123", 10);
console.log(hash);
 
const cocok = await bcrypt.compare("rahasia123", hash);
console.log(cocok);

bcrypt.hash("rahasia123", 10) menghasilkan string hash dengan cost factor 10, dan bcrypt.compare(password, hash) memverifikasi tanpa menyimpan atau membaca password asli. Simpan hash di database — jika database bocor, password pengguna tetap aman.

Token JWT

Struktur Token

JWT (JSON Web Token) adalah cara stateless untuk membawa identitas: token berisi header, payload, dan signature, disandikan dalam tiga bagian yang dipisahkan titik. Karena ditandatangani, isinya tidak bisa diubah tanpa sepengetahuan server.

JSTerbitkan dan verifikasi JWT
import jwt from "jsonwebtoken";
 
const token = jwt.sign(
  { userId: 42, role: "admin" },
  process.env.JWT_SECRET,
  { expiresIn: "1h" },
);
 
const payload = jwt.verify(token, process.env.JWT_SECRET);
console.log(payload.userId, payload.role);

jwt.sign(payload, secret, { expiresIn: "1h" }) menerbitkan token yang kedaluwarsa dalam satu jam, dan jwt.verify memeriksa keaslian serta kelayakannya. Nilai process.env.JWT_SECRET wajib disimpan di environment variable — jangan pernah hardcode di kode, karena kita akan bahas di episode 12.

Middleware Autentikasi

Melindungi Endpoint dengan Bearer Token

Klien mengirim token di header Authorization dengan format Bearer <token>. Middleware autentikasi memeriksa header, memverifikasi token, lalu menempelkan identitas ke req.user:

JSMiddleware autentikasi
function auth(req, res, next) {
  const header = req.headers.authorization;
  if (!header || !header.startsWith("Bearer ")) {
    return res.status(401).json({ error: "Token tidak ditemukan" });
  }
  try {
    req.user = jwt.verify(header.slice(7), process.env.JWT_SECRET);
    next();
  } catch {
    return res.status(401).json({ error: "Token tidak valid" });
  }
}

header.slice(7) mengambil token setelah kata Bearer . Jika token hilang, kadaluwarsa, atau rusak, middleware membalas 401 dan menghentikan rantai. Jika valid, req.user berisi payload yang siap dipakai handler berikutnya.

Memasang Middleware pada Route

Tempelkan auth pada route yang butuh proteksi:

JSRoute terproteksi
app.get("/api/profil", auth, (req, res) => {
  res.json({ userId: req.user.userId });
});

app.get("/api/profil", auth, ...) menyisipkan middleware auth di antara definisi route dan handler — hanya request dengan token valid yang sampai ke handler. Route publik seperti login tetap tanpa proteksi.

Otorisasi Berbasis Peran

Memeriksa Hak Akses

Autentikasi hanya menjawab siapa kalian. Otorisasi menjawab apa yang boleh kalian lakukan. Ketika payload JWT memuat role, buat middleware kedua untuk memeriksa peran:

JSOtorisasi berdasarkan peran
function role(peran) {
  return (req, res, next) => {
    if (req.user.role !== peran) {
      return res.status(403).json({ error: "Akses ditolak" });
    }
    next();
  };
}
 
app.delete("/api/pengguna/:id", auth, role("admin"), (req, res) => {
  res.json({ terhapus: req.params.id });
});

Pola role("admin") mengembalikan middleware yang membandingkan req.user.role dengan peran yang diizinkan. Perbedaan kode penting: 401 untuk belum terautentikasi, 403 untuk sudah login tapi tidak berhak. Endpoint penghapusan pengguna di atas hanya boleh dijalankan admin.

JWT dan Strategi Lain

JWT cocok untuk API dan aplikasi stateless. Untuk aplikasi web tradisional, session berbasis cookie sering lebih sederhana — kita bandingkan keduanya di episode 16. Kunci di episode ini: autentikasi dan otorisasi adalah dua lapis terpisah, masing-masing punya middleware sendiri, dan keduanya mudah diuji secara independen.

Penutup

Inti yang harus dibawa pulang:

  • Simpan password sebagai hash bcrypt, bukan teks polos atau enkripsi.
  • JWT membawa identitas stateless yang ditandatangani server.
  • JWT_SECRET disimpan di environment variable, tidak di kode.
  • Middleware auth memverifikasi token dan mengisi req.user.
  • 401 berarti belum login; 403 berarti tidak berhak.
  • role("admin") membatasi endpoint untuk peran tertentu.

Di episode 12 selanjutnya kita akan membahas logging, environment config, dan pengaturan runtime — memuat konfigurasi dari file .env, membedakan NODE_ENV, logging terstruktur dengan pino, serta level logging yang tepat untuk produksi. Konfigurasi yang rapi adalah syarat aplikasi yang bisa di-deploy.

Belajar Node.js - Autentikasi dan Otorisasi Dasar | Belajar Node.js