Autentikasi — API

Autentikasi memverifikasi siapa yang mengirim request. Token-based auth (paling umum untuk API): 1. Client login → POST /auth/login (email + password) 2…

Sampai sekarang siapa pun bisa memanggil semua endpoint Toko Buku. Padahal GET /profile harus tahu kamu siapa, dan DELETE /books/3 cuma boleh untuk admin. Autentikasi menjawab satu pertanyaan: siapa yang mengirim request ini? Bayangin gelang konser. Di loket kamu tunjukkan KTP sekali (login), lalu dapat gelang. Sesudah itu, tiap masuk area cukup tunjukkan gelangnya, penjaga gak menanyakan KTP lagi. Gelang itu token. Gelang palsu atau yang sudah lewat tanggalnya ditolak di pintu. Gelang asli kelas festival yang mau masuk area VIP juga ditolak, tapi dengan alasan lain.

🧪 Tebakan cepat: Siti login dengan benar dan punya token yang sah, tapi role-nya customer. Dia mengirim DELETE /books/3, yang cuma untuk admin. Server menjawab 401 atau 403? Tebak dulu, jawabannya ada di bagian "401 atau 403".

Token di header Authorization

  1. Client login sekali: POST /auth/login dengan email dan password. Server memeriksanya (cara menyimpan dan mencocokkan password ada di pelajaran Password Hashing di track Auth), lalu menjawab dengan token.
  2. Di tiap request berikutnya, client mengirim token itu di header Authorization:
GET /profile HTTP/1.1
Host: api.tokobuku.test
Authorization: Bearer valid-token-123

Middleware requireAuth

Pemeriksaannya ditaruh di middleware, function yang jalan sebelum handler dan boleh meneruskan atau menghentikan request:

function requireAuth(req, res, next) {
  const header = req.headers.authorization || "";
  const [scheme, token] = header.split(" ");
  if (scheme !== "Bearer" || token !== "valid-token-123") {
    res.set("WWW-Authenticate", 'Bearer realm="tokobuku"');
    return res.status(401).json({ error: "Unauthorized" });
  }
  next();
}

app.get("/profile", requireAuth, (req, res) => {
  res.json({ name: "Budi", role: "admin" });
});
Header Authorization Jawaban
(gak dikirim) 401
Bearer salah 401
valid-token-123 (tanpa Bearer) 401
Bearer valid-token-123 200

401 atau 403

Siti sudah dikenali dari tokennya, jadi bukan 401. Dia cuma gak berhak menghapus buku: 403. Itu jawaban tebakannya.

Siapa GET /profile DELETE /books/3
Tanpa token 401 401
Siti, customer 200 403
Budi, admin 200 204

Memeriksa role (siapa boleh apa) disebut authorization. Bedanya dengan autentikasi dibahas di pelajaran Authentication vs Authorization di track Auth.

Token yang ditandatangani

valid-token-123 gampang ditebak. Token sungguhan ada dua jenis: string acak panjang yang dicocokkan ke database, atau token yang ditandatangani. Yang kedua, misalnya JWT (JSON Web Token), terdiri dari tiga bagian dipisah titik: header.payload.signature.

const crypto = require("crypto");

function verify(token, secret) {
  const [header, payload, signature] = token.split(".");
  const expected = crypto.createHmac("sha256", secret).update(header + "." + payload).digest("base64url");
  if (signature !== expected) return null; // isinya diubah, atau bukan buatan server ini
  const data = JSON.parse(Buffer.from(payload, "base64url").toString());
  if (data.exp * 1000 < Date.now()) return null; // sudah kedaluwarsa
  return data;
}

Siti mengganti "role":"customer" jadi "role":"admin" di payload-nya. Server menghitung ulang signature-nya, hasilnya zNM3i5yo..., padahal token membawa RlA4atrp.... Gak cocok: 401. Di aplikasi sungguhan, pakai library (misalnya jsonwebtoken atau jose), simpan secret di environment variable, dan bandingkan signature dengan crypto.timingSafeEqual. Detailnya ada di pelajaran JSON Web Token (JWT) di track Auth.

API key atau token user

Token user API key
Mewakili satu orang yang login satu aplikasi atau server
Didapat dari POST /auth/login dibuat di dashboard
Umur pendek (menit sampai hari) panjang, sampai dicabut
Dikirim lewat Authorization: Bearer ... Authorization: Bearer ... atau X-API-Key: ...
Contoh aplikasi HP pembeli gudang yang sinkron stok tiap malam

Server menyimpan API key dalam bentuk hash, seperti password, supaya database yang bocor gak ikut membocorkan key-nya.

⚠️ Jebakan yang sering ketemu

TL;DR: Autentikasi menjawab "siapa yang mengirim request ini?". Client login sekali, lalu mengirim token di header Authorization dengan skema Bearer: Authorization: Bearer <token>. Middleware requireAuth membaca req.headers.authorization, memanggil next() kalau tokennya sah, dan menjawab 401 dengan {"error": "Unauthorized"} plus WWW-Authenticate kalau token gak ada, salah, atau kedaluwarsa. Dikenali tapi gak berhak, misalnya customer yang menghapus buku: 403. Token yang ditandatangani (JWT) punya payload yang bisa dibaca siapa saja dan signature HMAC-SHA256 yang cuma bisa dibuat pemegang secret, jadi payload yang diubah ketahuan. API key untuk aplikasi, token untuk user. Jangan simpan token di localStorage (rentan XSS) dan jangan kirim lewat query string.

Yang akan kamu pelajari