Dua konsep yang sering tertukar tapi sangat berbeda: Authentication (AuthN) dan Authorization (AuthZ).
Authentication — "Siapa kamu?" Proses memverifikasi identitas pengguna. Apakah kamu benar-benar orang yang kamu klaim?
Contoh authentication:
- Login dengan email dan password
- Scan sidik jari
- Login dengan Google/GitHub (Social Login)
- Memasukkan OTP dari SMS
Authorization — "Boleh apa?" Setelah identitas terverifikasi, proses menentukan apa saja yang boleh dilakukan pengguna.
Contoh authorization:
- User biasa boleh baca artikel, tapi tidak boleh menghapus
- Admin boleh mengelola semua data
- Editor boleh mengedit konten, tapi tidak boleh mengubah pengaturan
Analogi: Bayangkan masuk ke gedung kantor:
- Authentication = security memeriksa kartu ID kamu (memverifikasi identitas)
- Authorization = kartu ID kamu menentukan lantai mana yang boleh kamu akses
Alur lengkap:
User mengirim kredensial (email + password)
↓
Server memverifikasi identitas (Authentication)
↓
Server mengeluarkan token/session
↓
User mengirim token di setiap request
↓
Server memeriksa apa yang boleh dilakukan user (Authorization)
↓
Server mengembalikan data atau menolak (403 Forbidden)
Implementasi dasar:
// Authentication — verifikasi identitas
async function authenticate(email, password) {
const user = await db.findUserByEmail(email);
if (!user) return null; // user tidak ditemukan
const valid = await bcrypt.compare(password, user.passwordHash);
if (!valid) return null; // password salah
return user; // identitas terverifikasi!
}
// Authorization — cek izin
function authorize(user, action, resource) {
const permissions = {
admin: ["create", "read", "update", "delete"],
editor: ["create", "read", "update"],
viewer: ["read"]
};
const allowed = permissions[user.role] || [];
return allowed.includes(action);
}
// Penggunaan:
const user = await authenticate("[email protected]", "password123");
if (!user) return res.status(401).json({ error: "Login gagal" });
if (!authorize(user, "delete", "article")) {
return res.status(403).json({ error: "Tidak punya izin" });
}
Status code yang tepat:
401 Unauthorized— sebenarnya lebih tepat "Unauthenticated" (belum login)403 Forbidden— sudah login tapi tidak punya izin (authorization gagal)
Memahami perbedaan ini penting karena strategi penanganannya berbeda: 401 → minta user login ulang, 403 → tampilkan pesan "akses ditolak".
💡 Bug klasik: banyak app return 403 padahal user belum login. Atau return 401 padahal user udah login tapi gak punya akses. Salah status code = client gagal handle (gak tau mau redirect ke login page atau show "access denied"). Wajib bedain.
🎭 Analogi sehari-hari
Authentication (AuthN) = satpam cek KTP di pintu masuk gedung. "Beneran kamu Budi?" Authorization (AuthZ) = kartu akses di lift. KTP kamu valid (AuthN passed), tapi kartu akses kamu cuma boleh sampai lantai 3 (AuthZ check). Dua proses berbeda, dua kegagalan berbeda: gak punya KTP (401) vs KTP valid tapi gak boleh ke lantai 10 (403).
⚠️ Jebakan yang sering ditemui
- Plain text password = wajib hashing (bcrypt/argon2). Plain = security disaster
- JWT secret bocor = penyerang bisa generate token valid. Rotate jika curiga
- Authorization di frontend saja = bisa di-bypass DevTools. Server WAJIB cek juga
- Session cookie tanpa
httpOnly= JavaScript bisa baca = XSS curi token - Lupa logout invalidate session = curi token valid forever
- Reuse password antar service kalau database satu bocor = semua bocor
TL;DR: Auth = 2 hal berbeda. Authentication = "siapa kamu?" (login, OTP, biometric). Authorization = "boleh apa?" (role, permission). HTTP status: 401 = belum auth, 403 = auth OK tapi gak boleh. Kategori ini bahas: hashing, session vs JWT, OAuth, MFA, CSRF, dll. Wajib di setiap app dengan user.