Tutorial PHP: Membuat Sistem Login & Registrasi Lengkap dari Nol (Sampai Bisa Dipakai)

Hampir semua aplikasi web — dari toko online sampai sistem kasir — butuh halaman login dan registrasi. Di tutorial ini kita bikin sistem login & registrasi lengkap dan berfungsi dari nol pakai PHP native + MySQL. Semua kode bisa langsung kamu copy-paste, dan di akhir ada langkah verifikasinya.

1. Persiapan: PHP & MySQL

Kamu butuh PHP 8.0+ dan MySQL/MariaDB. Kalau belum ada, install XAMPP (Windows/Mac/Linux) atau jalankan di server Linux dengan perintah:

php -v        # pastikan PHP terinstall
mysql --version  # pastikan MySQL terinstall

Buat folder proyek, misalnya login-app, dan buat file-file berikut di dalamnya:

login-app/
├── koneksi.php     (koneksi database)
├── register.php    (form + proses registrasi)
├── login.php       (form + proses login)
├── dashboard.php   (halaman khusus member)
└── logout.php      (keluar)

2. Buat Database & Tabel Users

Masuk ke MySQL lalu buat database dan tabelnya:

CREATE DATABASE login_app CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE login_app;

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nama VARCHAR(100) NOT NULL,
    email VARCHAR(150) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

3. File koneksi.php — Koneksi Database

Kita pakai PDO (lebih aman dari SQL injection dibanding mysql_query lama). Simpan sebagai koneksi.php:

<?php
$host = 'localhost';
$db   = 'login_app';
$user = 'root';
$pass = '';   // sesuaikan password MySQL kamu

try {
    $pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8mb4", $user, $pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die('Koneksi gagal: ' . $e->getMessage());
}

4. File register.php — Form & Proses Registrasi

Password wajib di-hash, jangan pernah disimpan mentah. PHP punya fungsi password_hash() untuk ini:

<?php
session_start();
require 'koneksi.php';

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

    if (strlen($nama) < 3) {
        $errors[] = 'Nama minimal 3 karakter.';
    }
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errors[] = 'Format email tidak valid.';
    }
    if (strlen($password) < 6) {
        $errors[] = 'Password minimal 6 karakter.';
    }

    if (!$errors) {
        $cek = $pdo->prepare('SELECT id FROM users WHERE email = ?');
        $cek->execute([$email]);
        if ($cek->fetch()) {
            $errors[] = 'Email sudah terdaftar. Silakan login.';
        } else {
            $hash = password_hash($password, PASSWORD_DEFAULT);
            $stmt = $pdo->prepare('INSERT INTO users (nama, email, password) VALUES (?, ?, ?)');
            $stmt->execute([$nama, $email, $hash]);
            $_SESSION['success'] = 'Registrasi berhasil! Silakan login.';
            header('Location: login.php');
            exit;
        }
    }
}
?>
<!DOCTYPE html>
<html lang="id">
<head><meta charset="UTF-8"><title>Registrasi</title></head>
<body>
<h1>Registrasi Akun</h1>
<?php foreach ($errors as $e): ?>
<p style="color:red"><?= htmlspecialchars($e) ?></p>
<?php endforeach; ?>
<form method="post">
    Nama: <input type="text" name="nama" required><br><br>
    Email: <input type="email" name="email" required><br><br>
    Password: <input type="password" name="password" required><br><br>
    <button type="submit">Daftar</button>
</form>
<p>Sudah punya akun? <a href="login.php">Login di sini</a></p>
</body>
</html>

5. File login.php — Form & Proses Login

Proses login: cari user berdasarkan email, lalu verifikasi password dengan password_verify(). Kalau cocok, simpan info user di session:

<?php
session_start();
require 'koneksi.php';

if (isset($_SESSION['user_id'])) {
    header('Location: dashboard.php');
    exit;
}

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

    $stmt = $pdo->prepare('SELECT id, nama, email, password FROM users WHERE email = ?');
    $stmt->execute([$email]);
    $user = $stmt->fetch(PDO::FETCH_ASSOC);

    if ($user && password_verify($password, $user['password'])) {
        session_regenerate_id(true); // cegah session fixation
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['user_nama'] = $user['nama'];
        header('Location: dashboard.php');
        exit;
    } else {
        $error = 'Email atau password salah.';
    }
}
?>
<!DOCTYPE html>
<html lang="id">
<head><meta charset="UTF-8"><title>Login</title></head>
<body>
<h1>Login</h1>
<?php if (isset($_SESSION['success'])): ?>
<p style="color:green"><?= htmlspecialchars($_SESSION['success']) ?></p>
<?php unset($_SESSION['success']); endif; ?>
<?php if ($error): ?>
<p style="color:red"><?= htmlspecialchars($error) ?></p>
<?php endif; ?>
<form method="post">
    Email: <input type="email" name="email" required><br><br>
    Password: <input type="password" name="password" required><br><br>
    <button type="submit">Login</button>
</form>
<p>Belum punya akun? <a href="register.php">Daftar di sini</a></p>
</body>
</html>

6. File dashboard.php — Halaman Khusus Member

Halaman ini hanya bisa dibuka kalau sudah login. Kalau belum, lempar ke halaman login:

<?php
session_start();
if (!isset($_SESSION['user_id'])) {
    header('Location: login.php');
    exit;
}
?>
<!DOCTYPE html>
<html lang="id">
<head><meta charset="UTF-8"><title>Dashboard</title></head>
<body>
<h1>Selamat datang, <?= htmlspecialchars($_SESSION['user_nama']) ?>!</h1>
<p>Kamu berhasil login. Ini adalah halaman khusus member.</p>
<p><a href="logout.php">Logout</a></p>
</body>
</html>

7. File logout.php — Keluar

<?php
session_start();
$_SESSION = [];
session_destroy();
header('Location: login.php');
exit;

8. Jalankan & Tes dari Nol

Jalankan server PHP bawaan dari folder proyek:

cd login-app
php -S localhost:8000

Sekarang tes alurnya di browser:

1. Buka http://localhost:8000/register.php
   → Isi nama, email, password (min. 6 karakter) → klik Daftar
   → Harusnya diarahkan ke login.php dengan pesan "Registrasi berhasil!"
2. Buka http://localhost:8000/dashboard.php TANPA login dulu
   → Harusnya langsung dilempar ke login.php (halaman terproteksi)
3. Login dengan email & password yang tadi didaftarkan
   → Harusnya masuk ke dashboard dan tampil "Selamat datang, [nama]!"
4. Klik Logout → coba buka dashboard.php lagi
   → Harusnya kembali ke halaman login

Verifikasi data tersimpan dengan benar di MySQL — password harus berupa hash, bukan teks mentah:

mysql -u root -e "SELECT id, nama, email, LEFT(password, 20) AS hash_awal FROM login_app.users;"

Contoh output yang benar (kolom password diawali $2y$, tanda password sudah di-hash bcrypt):

+----+-------+------------------+----------------------+
| id | nama  | email            | hash_awal            |
+----+-------+------------------+----------------------+
|  1 | Budi  | budi@mail.com    | $2y$10$Kj8vNm3...    |
+----+-------+------------------+----------------------+

9. Tips Keamanan Lanjutan

Sistem di atas sudah cukup untuk belajar, tapi untuk aplikasi produksi tambahkan ini:

- Tambahkan HTTPS (sertifikat SSL) agar password tidak terkirim polos
- Tambahkan rate limiting: batasi 5x percobaan login per menit per IP
- Tambahkan verifikasi email (kirim link aktivasi via email)
- Tambahkan fitur "Lupa Password" dengan token sekali pakai
- Simpan kredensial database di file .env, bukan di kode

Kesimpulan

Kamu sekarang punya sistem login & registrasi lengkap: database, koneksi PDO yang aman dari SQL injection, registrasi dengan validasi, password yang di-hash bcrypt, login dengan session, halaman terproteksi, dan logout. Pola ini adalah fondasi hampir semua aplikasi web PHP — dari sistem kasir sampai panel admin UMKM. Selanjutnya, coba kembangkan: tambah fitur lupa password atau verifikasi email. Selamat ngoding! Ditulis oleh tim RPL United.

Komentar

Postingan populer dari blog ini