⚠️ Persiapan Database & Keamanan Password
Sebelum kita bikin fitur login, web kita butuh data siapa saja yang boleh masuk. Kita harus bikin tabel baru dengan nama user di database.
Karena kita akan mengenkripsi password (tidak menyimpannya dalam bentuk teks asli), pastikan kolom password menggunakan tipe data VARCHAR dengan panjang minimal 255.
Silahkan jalankan query SQL berikut di phpMyAdmin kalian:
CREATE TABLE user (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL
);
Bagaimana cara memasukkan admin pertama kali? Karena password akan dienkripsi menggunakan algoritma Bcrypt bawaan PHP, kita tidak bisa asal mengetik "admin123" di phpMyAdmin. Kita butuh script PHP bantuan untuk membuatkan password yang sudah di-hash.
Buat file sementara bernama setup.php, isi dengan kode berikut, lalu jalankan di browser:
<?php
include "koneksi.php";
$username = "admin";
$password_asli = "admin123";
// Mengenkripsi password
$password_hash = password_hash($password_asli, PASSWORD_DEFAULT);
// Masukkan ke database
mysqli_query($conn, "INSERT INTO user (username, password) VALUES ('$username', '$password_hash')");
echo "Admin berhasil dibuat! Silahkan hapus file setup.php ini.";
?>
Penting: Setelah script dijalankan dan muncul tulisan berhasil, langsung hapus file
setup.phpagar tidak disalahgunakan! Jika kalian cek di database, password yang tersimpan sekarang akan berbentuk acak seperti$2y$10$xyz...
Langkah 10 - Membuat Halaman Login (login.php)
Sekarang kita buat fitur untuk mengecek kecocokan inputan user dengan password acak yang ada di database.
Buat file bernama login.php, lalu ketikkan kode berikut:
<?php
// Wajib ditaruh paling atas untuk memulai session
session_start();
include "koneksi.php";
// Kalau tombol login ditekan
if (isset($_POST['login'])) {
$username = $_POST['username'];
$password = $_POST['password'];
// 1. Cari user berdasarkan username saja
$cek = mysqli_query($conn, "SELECT * FROM user WHERE username='$username'");
// 2. Cek apakah username ditemukan
if (mysqli_num_rows($cek) === 1) {
// Ambil data user tersebut
$data = mysqli_fetch_assoc($cek);
// 3. Verifikasi password yang diketik dengan hash di database
if (password_verify($password, $data['password'])) {
// Jika cocok, buat session
$_SESSION['status'] = "login";
$_SESSION['username'] = $username;
// Pindahkan ke halaman utama
header("Location: index.php");
exit; // Hentikan script
} else {
$error = "Password yang Anda masukkan salah!";
}
} else {
$error = "Username tidak ditemukan!";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Login Sistem</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<body class="bg-light d-flex align-items-center" style="height: 100vh;">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-4">
<div class="card shadow-sm">
<div class="card-body">
<h3 class="text-center mb-4">Login</h3>
<?php if(isset($error)) { ?>
<div class="alert alert-danger"><?= $error ?></div>
<?php } ?>
<form method="POST">
<div class="mb-3">
<label>Username</label>
<input type="text" name="username" class="form-control" required>
</div>
<div class="mb-4">
<label>Password</label>
<input type="password" name="password" class="form-control" required>
</div>
<button type="submit" name="login" class="btn btn-primary w-100">Masuk</button>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Penjelasan Kode login.php:
1. Mengenkripsi Password Baru (pada file setup)
$password_hash = password_hash($password_asli, PASSWORD_DEFAULT);
Fungsi password_hash() adalah fitur keamanan modern dari PHP. Fungsi ini mengubah teks biasa (seperti "admin123") menjadi teks acak yang panjang.
2. Query Hanya Mencari Username
$cek = mysqli_query($conn, "SELECT * FROM user WHERE username='$username'");
Berbeda dengan sistem lama, di sini kita tidak mengecek kecocokan password di dalam query SQL. Kita cuma nanya ke database: "Ada nggak data yang namanya username ini?".
3. Verifikasi Password Enkripsi
if (password_verify($password, $data['password'])) {
// Berhasil masuk
}
Inilah jantung keamanannya. Fungsi password_verify() bertugas mencocokkan password biasa yang diketik user ($password) dengan password acak yang tersimpan di dalam database ($data['password']). PHP akan otomatis menerjemahkan dan mengecek apakah keduanya cocok.
Langkah 11 - Mengunci Halaman (Proteksi URL)
Saat ini, orang masih bisa langsung mengetik localhost/project/index.php di URL tanpa harus login. Kita harus "mengunci" file index.php, tambah.php, edit.php, dan hapus.php.
Buka file index.php (dan file CRUD lainnya), tambahkan kode ini di BARIS PALING ATAS (sebelum tag <!DOCTYPE html>):
<?php
session_start();
// Cek apakah user sudah punya tiket login
if (!isset($_SESSION['status']) || $_SESSION['status'] != "login") {
// Kalau belum login, tendang balik ke halaman login
header("Location: login.php");
exit(); // Hentikan eksekusi kode di bawahnya
}
include "koneksi.php";
// ... (kode index.php yang lama dilanjutkan di sini) ...
?>
Penjelasan Kode Proteksi:
Kita mengecek session status. Kalau session tersebut belum dibuat atau nilainya bukan "login" (berarti user berusaha masuk dari jalur URL), fungsi header("Location: login.php") akan langsung membuang user kembali ke halaman form login.
(Catatan: Jangan lupa tambahkan tombol Logout di file index.php kalian, misalnya di atas tabel produk: <a href="logout.php" class="btn btn-danger mb-3">Logout</a>)
Langkah 12 - Membuat Fitur Logout (logout.php)
Setelah bisa masuk, user harus bisa keluar dan menghapus session (tiket masuk)-nya. Buat file baru bernama logout.php dengan kode ini:
<?php
// Wajib panggil session_start() dulu
session_start();
// Hapus semua data session
session_destroy();
// Arahkan kembali ke halaman login
header("Location: login.php");
exit;
?>
Penjelasan Kode logout.php:
session_destroy(): Fungsi ini bertugas menghancurkan semua data$_SESSIONyang pernah dibuat. Setelah baris ini dieksekusi, web sudah tidak mengenali user lagi dan status loginnya kembali kosong.