Tutorial PHP #29: Authentication Login Register dengan PHP

1. Apa itu Authentication?

Authentication adalah proses memverifikasi identitas user - memastikan user yang mengakses aplikasi benar-benar yang mereka klaim. Alur dasar: Register (daftar akun) → Login (masuk) → Protect Page (halaman yang hanya bisa diakses setelah login) → Logout (keluar).

2. Register - Membuat Akun

<?php
// register.php
require_once "db.php";

$errors  = [];
$success = false;

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $nama     = trim($_POST["nama"]     ?? "");
    $email    = trim($_POST["email"]    ?? "");
    $password = trim($_POST["password"] ?? "");
    $confirm  = trim($_POST["confirm"]  ?? "");

    // Validasi
    if (empty($nama))                                    $errors[] = "Nama wajib diisi";
    if (!filter_var($email, FILTER_VALIDATE_EMAIL))      $errors[] = "Format email tidak valid";
    if (strlen($password) < 8)                          $errors[] = "Password minimal 8 karakter";
    if ($password !== $confirm)                          $errors[] = "Konfirmasi password tidak cocok";

    // Cek apakah email sudah terdaftar
    if (empty($errors)) {
        $stmt = $pdo->prepare("SELECT id FROM users WHERE email = :email");
        $stmt->execute(["email" => $email]);
        if ($stmt->fetch()) {
            $errors[] = "Email sudah terdaftar";
        }
    }

    // Simpan ke database
    if (empty($errors)) {
        $hashedPass = password_hash($password, PASSWORD_DEFAULT);
        $stmt = $pdo->prepare(
            "INSERT INTO users (nama, email, password) VALUES (:nama, :email, :password)"
        );
        $stmt->execute(["nama" => $nama, "email" => $email, "password" => $hashedPass]);
        $success = true;
    }
}
?>
<?php if ($success): ?>
    <p style="color:green">Registrasi berhasil! <a href="login.php">Silakan login</a></p>
<?php else: ?>
    <?php foreach ($errors as $err): ?>
        <p style="color:red"><?= htmlspecialchars($err) ?></p>
    <?php endforeach; ?>
    <form method="POST">
        <input type="text" name="nama" placeholder="Nama lengkap"><br>
        <input type="email" name="email" placeholder="Email"><br>
        <input type="password" name="password" placeholder="Password (min 8 karakter)"><br>
        <input type="password" name="confirm" placeholder="Konfirmasi password"><br>
        <button type="submit">Daftar</button>
    </form>
<?php endif; ?>

3. Login - Verifikasi User

<?php
// login.php
session_start();
require_once "db.php";

// Jika sudah login, redirect ke dashboard
if (isset($_SESSION["user_id"])) {
    header("Location: dashboard.php");
    exit;
}

$error = "";

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $email    = trim($_POST["email"]    ?? "");
    $password = trim($_POST["password"] ?? "");

    if (empty($email) || empty($password)) {
        $error = "Email dan password wajib diisi";
    } else {
        // Cari user berdasarkan email
        $stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email LIMIT 1");
        $stmt->execute(["email" => $email]);
        $user = $stmt->fetch();

        // Verifikasi password dengan password_verify()
        if ($user && password_verify($password, $user["password"])) {
            // Login berhasil - buat session
            $_SESSION["user_id"]    = $user["id"];
            $_SESSION["user_nama"]  = $user["nama"];
            $_SESSION["user_email"] = $user["email"];
            $_SESSION["user_role"]  = $user["role"] ?? "user";
            $_SESSION["logged_in"]  = true;

            // Regenerate session ID untuk keamanan (cegah session fixation)
            session_regenerate_id(true);

            header("Location: dashboard.php");
            exit;
        } else {
            $error = "Email atau password salah";
        }
    }
}
?>
<?php if ($error): ?>
    <p style="color:red"><?= htmlspecialchars($error) ?></p>
<?php endif; ?>
<form method="POST">
    <input type="email" name="email" placeholder="Email"><br>
    <input type="password" name="password" placeholder="Password"><br>
    <button type="submit">Login</button>
</form>

4. Protect Page - Halaman yang Butuh Login

<?php
// auth.php - helper untuk cek login
function requireLogin(): void {
    session_start();
    if (!isset($_SESSION["logged_in"]) || !$_SESSION["logged_in"]) {
        header("Location: login.php?redirect=" . urlencode($_SERVER["REQUEST_URI"]));
        exit;
    }
}

function requireRole(string $role): void {
    requireLogin();
    if ($_SESSION["user_role"] !== $role) {
        http_response_code(403);
        die("<h1>403 Forbidden</h1><p>Kamu tidak punya akses ke halaman ini.</p>");
    }
}
?>
<?php
// dashboard.php
require_once "auth.php";
requireLogin();   // redirect ke login.php jika belum login
require_once "db.php";
?>
<h1>Dashboard</h1>
<p>Selamat datang, <?= htmlspecialchars($_SESSION["user_nama"]) ?>!</p>
<a href="logout.php">Logout</a>

5. Logout

<?php
// logout.php
session_start();
session_unset();
session_destroy();

// Hapus session cookie
if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(session_name(), "", time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
}

header("Location: login.php?logout=1");
exit;
?>

6. Ringkasan

  • Selalu hash password dengan password_hash(), jangan simpan plain text
  • Verifikasi password dengan password_verify() - jangan compare langsung
  • Gunakan session_regenerate_id(true) setelah login untuk cegah session fixation
  • Buat helper function untuk mengecek status login di setiap halaman terproteksi

Tutorial berikutnya membahas mini project PHP native - menggabungkan semua yang sudah dipelajari!