Authentication vs Authorization

Dua konsep ini sering tertukar, padahal perannya sangat berbeda. Memahami perbedaannya adalah fondasi penting untuk membangun sistem yang aman.

Perbedaan Mendasar

Authentication (AuthN)Authorization (AuthZ)
Pertanyaan"Siapa kamu?""Apa yang boleh kamu lakukan?"
ProsesVerifikasi identitasVerifikasi izin/hak akses
KapanSaat loginSetelah login, di setiap halaman
ContohUsername + PasswordAdmin boleh hapus, User hanya baca
AnalogiTunjukkan KTP ke satpamKartu akses β€” lantai mana yang boleh masuk
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚ AUTHENTICATIONβ”‚         β”‚ AUTHORIZATION β”‚
     β”‚  "Siapa kamu?"β”‚         β”‚ "Boleh tidak?"β”‚
     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚                        β”‚
    User: admin                Role: admin
    Pass: ****                 β†’ Boleh akses semua βœ…
            β”‚                        β”‚
    User: kasir                Role: kasir
    Pass: ****                 β†’ Hanya lihat & input ⚠️
            β”‚                        β”‚
    User: tamu                 Role: guest
    (tidak login)              β†’ Hanya halaman publik 🚫

Implementasi: Sistem Role (Peran)

1. Tambah Kolom Role di Tabel Users

ALTER TABLE users ADD COLUMN role ENUM('admin', 'editor', 'user') DEFAULT 'user';

-- Update admin yang sudah ada
UPDATE users SET role = 'admin' WHERE username = 'admin';

2. Simpan Role di Session Saat Login

<?php
// login.php β€” setelah password_verify berhasil
if ($user && password_verify($password, $user['password'])) {
    $_SESSION['user_id'] = $user['id'];
    $_SESSION['username'] = $user['username'];
    $_SESSION['nama_lengkap'] = $user['nama_lengkap'];
    $_SESSION['role'] = $user['role'];  // ← Simpan role

    header('Location: dashboard.php');
    exit;
}

3. Helper Function untuk Authorization

<?php
// config/auth.php

session_start();

/**
 * Cek apakah user sudah login (Authentication)
 */
function cekLogin(): void {
    if (!isset($_SESSION['user_id'])) {
        header('Location: /login.php');
        exit;
    }
}

/**
 * Cek apakah user sudah login
 */
function isLogin(): bool {
    return isset($_SESSION['user_id']);
}

/**
 * Ambil role user saat ini
 */
function getRole(): string {
    return $_SESSION['role'] ?? 'guest';
}

/**
 * Cek apakah user punya role tertentu (Authorization)
 */
function hasRole(string ...$roles): bool {
    return in_array(getRole(), $roles);
}

/**
 * Paksa user harus punya role tertentu β€” redirect jika tidak
 */
function requireRole(string ...$roles): void {
    cekLogin();  // Harus login dulu (authentication)

    if (!hasRole(...$roles)) {
        http_response_code(403);
        include __DIR__ . '/../templates/403.php';  // Halaman "Akses Ditolak"
        exit;
    }
}

/**
 * Ambil info user yang sedang login
 */
function currentUser(): array {
    return [
        'id' => $_SESSION['user_id'] ?? null,
        'username' => $_SESSION['username'] ?? 'Guest',
        'nama' => $_SESSION['nama_lengkap'] ?? 'Guest',
        'role' => $_SESSION['role'] ?? 'guest',
    ];
}

4. Gunakan di Halaman yang Dilindungi

<?php
// halaman-admin.php β€” Hanya admin yang boleh akses
require 'config/auth.php';
requireRole('admin');

// Kode di bawah ini hanya dieksekusi jika user = admin
echo "<h1>Dashboard Admin</h1>";
echo "<p>Selamat datang, " . htmlspecialchars(currentUser()['nama']) . "!</p>";
<?php
// kelola-produk.php β€” Admin dan editor boleh akses
require 'config/auth.php';
requireRole('admin', 'editor');

echo "<h1>Kelola Produk</h1>";
<?php
// profil.php β€” Semua user yang login boleh akses
require 'config/auth.php';
cekLogin();  // Hanya cek authentication, tidak cek role

echo "<h1>Profil: " . htmlspecialchars(currentUser()['nama']) . "</h1>";

5. Kontrol Tampilan Berdasarkan Role

<!-- menu.php -->
<nav>
    <a href="/">Beranda</a>
    <a href="/produk.php">Produk</a>

    <?php if (isLogin()): ?>
        <a href="/profil.php">Profil</a>

        <?php if (hasRole('admin', 'editor')): ?>
            <a href="/kelola-produk.php">Kelola Produk</a>
        <?php endif; ?>

        <?php if (hasRole('admin')): ?>
            <a href="/kelola-user.php">πŸ‘‘ Kelola User</a>
        <?php endif; ?>

        <a href="/logout.php">Logout (<?= htmlspecialchars(currentUser()['username']) ?>)</a>
    <?php else: ?>
        <a href="/login.php">Login</a>
    <?php endif; ?>
</nav>
WARNING

Kontrol tampilan BUKAN keamanan!tidak cukup. Hacker bisa langsung akses URL-nya. Selalu tambahkan requireRole() di setiap halaman yang harusnya terlindungi.

6. Halaman 403 (Akses Ditolak)

<!-- templates/403.php -->
<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <title>Akses Ditolak</title>
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background: #f8f9fa;
            margin: 0;
        }
        .error-box {
            text-align: center;
            padding: 40px;
            background: white;
            border-radius: 16px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.1);
        }
        .error-box h1 { font-size: 64px; margin: 0; }
        .error-box p { color: #666; font-size: 18px; }
        .error-box a { color: #667eea; text-decoration: none; }
    </style>
</head>
<body>
    <div class="error-box">
        <h1>🚫</h1>
        <h2>403 β€” Akses Ditolak</h2>
        <p>Kamu tidak memiliki izin untuk mengakses halaman ini.</p>
        <p><a href="/">← Kembali ke Beranda</a></p>
    </div>
</body>
</html>

Matriks Hak Akses

Definisikan dengan jelas siapa bisa apa:

FiturGuestUserEditorAdmin
Lihat produkβœ…βœ…βœ…βœ…
Beli produkβŒβœ…βœ…βœ…
Tambah produkβŒβŒβœ…βœ…
Edit produkβŒβŒβœ…βœ…
Hapus produkβŒβŒβŒβœ…
Kelola userβŒβŒβŒβœ…

Keamanan Tambahan

<?php
// 1. Regenerasi session ID setelah login (cegah session fixation)
session_regenerate_id(true);

// 2. Set session cookie yang aman
ini_set('session.cookie_httponly', '1');  // Cookie tidak bisa diakses JavaScript
ini_set('session.cookie_secure', '1');   // Cookie hanya dikirim via HTTPS
ini_set('session.cookie_samesite', 'Strict');  // Cegah CSRF

// 3. Set timeout session (auto-logout setelah 30 menit idle)
$maxIdle = 1800;  // 30 menit dalam detik
if (isset($_SESSION['terakhir_aktif']) && (time() - $_SESSION['terakhir_aktif'] > $maxIdle)) {
    session_unset();
    session_destroy();
    header('Location: /login.php?timeout=1');
    exit;
}
$_SESSION['terakhir_aktif'] = time();
NOTE
  • Authentication: Auth::attempt(), Auth::check()
  • Authorization: Gate, Policy, @can directive di Blade
  • Middleware: auth, verified, can:admin

Semua yang kamu pelajari di sini adalah fondasi dari apa yang Laravel otomasi.

Latihan

  1. Tambahkan kolom role di tabel users dan buat 3 user: admin, editor, user biasa
  2. Update config/auth.php dengan helper function hasRole() dan requireRole()
  3. Buat halaman admin dashboard yang hanya bisa diakses role admin
  4. Buat menu navigasi yang otomatis menyembunyikan link berdasarkan role

Selanjutnya

Kamu sudah paham cara mengamankan siapa boleh apa. Lanjut ke Front Controller Pattern β†’ untuk belajar arsitektur routing yang dipakai semua framework modern.

Artikel Terkait