Membangun CMS Sederhana dengan PHP & MySQL - Part 2: Sistem Login Aman & Dashboard Admin Dasar
Selamat datang kembali di seri tutorial “Membangun CMS Sederhana dengan PHP & MySQL”! Di Part 1, kita telah berhasil membangun tampilan depan (frontend) yang menampilkan daftar artikel dan halaman detail artikel dari database. Sekarang, saatnya kita beralih ke sisi backend dan mulai membangun Area Admin – pusat kendali untuk mengelola konten CMS kita.
Fokus utama kita di Part 2 ini adalah:
- Membuat sistem login yang aman untuk administrator.
- Menggunakan sesi PHP untuk melacak status login pengguna.
- Mengimplementasikan hashing password untuk keamanan kredensial.
- Membangun halaman dashboard admin dasar sebagai titik awal setelah login berhasil.
- Membuat mekanisme logout.
- Melindungi halaman-halaman admin dari akses tidak sah.
Prasyarat
Pastikan Anda telah menyelesaikan atau memahami materi dari Part 1 karena kita akan membangun di atas struktur dan database yang telah dibuat. Anda juga memerlukan:
- Lingkungan pengembangan PHP & MySQL yang berjalan (XAMPP, MAMP, dll.).
- Pemahaman tentang sesi PHP dan dasar-dasar keamanan web.
Persiapan Database: Tabel users
Untuk sistem login, kita memerlukan tabel users
untuk menyimpan informasi administrator.
-
Buka phpMyAdmin dan pilih database
cms_sederhana_db
Anda. -
Jalankan query SQL berikut untuk membuat tabel
users
:CREATE TABLE `users` ( `id` INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY, `username` VARCHAR(50) NOT NULL UNIQUE, `email` VARCHAR(100) NOT NULL UNIQUE, `password` VARCHAR(255) NOT NULL COMMENT 'Hashed password', `role` VARCHAR(20) NOT NULL DEFAULT 'editor' COMMENT 'admin, editor', `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Penjelasan Tabel
users
:username
danemail
: Harus unik.password
: Akan menyimpan hash password, bukan password plaintext. Ini sangat penting untuk keamanan.role
: Untuk menentukan hak akses pengguna (misalnya,admin
bisa melakukan segalanya,editor
hanya bisa mengelola artikel). Defaultnyaeditor
.
-
Membuat User Admin Awal (Manual): Kita perlu setidaknya satu user admin untuk bisa login. Karena kita belum membuat fitur registrasi admin, kita akan menambahkannya secara manual ke database. PENTING: Kita akan menghash password menggunakan PHP.
Buat file sementara, misalnya
create_admin.php
di root proyek Anda, dengan isi:<?php // create_admin.php $password_plain = 'admin123'; // Ganti dengan password yang kuat $hashed_password = password_hash($password_plain, PASSWORD_DEFAULT); echo "Password Plain: " . $password_plain . "<br>"; echo "Hashed Password: " . $hashed_password; // Sekarang, salin nilai $hashed_password ini dan masukkan manual ke database // atau jalankan query INSERT di bawah ini setelah mendapatkan hashnya. ?>
Jalankan file ini di browser Anda (misalnya,
http://localhost/cms_sederhana_project/create_admin.php
). Salin output Hashed Password.Kemudian, di phpMyAdmin, masukkan user admin baru ke tabel
users
(via tab “Insert” atau SQL):INSERT INTO `users` (`username`, `email`, `password`, `role`) VALUES ('admin', 'admin@example.com', 'NILAI_HASHED_PASSWORD_DARI_PHP', 'admin');
Ganti
NILAI_HASHED_PASSWORD_DARI_PHP
dengan hash yang Anda dapatkan. Setelah selesai, hapus filecreate_admin.php
demi keamanan.
Struktur Folder Admin
Kita akan membuat subdirektori admin
di dalam root proyek untuk semua file terkait backend.
Perbarui struktur folder proyek Anda:
cms_sederhana_project/
├── admin/
│ ├── index.php // Dashboard admin (akan dibuat)
│ ├── login.php // Halaman login admin (akan dibuat)
│ ├── logout.php // Skrip logout (akan dibuat)
│ ├── auth_check.php // Skrip untuk otentikasi (akan dibuat)
│ ├── includes/ // Header/footer khusus admin (opsional)
│ │ ├── header_admin.php
│ │ └── footer_admin.php
│ └── (file manajemen konten lainnya akan ditambahkan di part berikutnya)
├── index.php
├── single.php
├── includes/
│ ├── db_connect.php
│ ├── header.php
│ ├── footer.php
│ └── functions.php
├── css/
│ └── style.css
│ └── admin_style.css // (Opsional) CSS khusus admin
├── js/
└── uploads/
Langkah 1: Halaman Login Admin (admin/login.php
)
Ini adalah gerbang masuk ke area admin.
Buat file admin/login.php
:
<?php
// admin/login.php
// Mulai sesi (harus menjadi baris pertama atau salah satu yang paling awal)
session_start();
// Jika pengguna sudah login, redirect ke dashboard admin
if (isset($_SESSION['user_id'])) {
header("Location: index.php");
exit;
}
// Sertakan file koneksi database
require_once '../includes/db_connect.php'; // Path relatif ke file koneksi
$login_error = ''; // Variabel untuk menyimpan pesan error login
// Proses form jika metode request adalah POST
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$username_or_email = trim($_POST['username_or_email']);
$password = trim($_POST['password']);
// Validasi input dasar
if (empty($username_or_email) || empty($password)) {
$login_error = "Username/Email dan Password tidak boleh kosong.";
} else {
// Sanitasi input sebelum digunakan dalam query (meskipun kita akan menggunakan prepared statements)
$username_or_email_safe = mysqli_real_escape_string($conn, $username_or_email);
// Query untuk mencari user berdasarkan username atau email
// Penggunaan prepared statement sangat direkomendasikan untuk keamanan
$sql = "SELECT id, username, password, role FROM users WHERE username = ? OR email = ?";
if ($stmt = mysqli_prepare($conn, $sql)) {
mysqli_stmt_bind_param($stmt, "ss", $username_or_email_safe, $username_or_email_safe);
if (mysqli_stmt_execute($stmt)) {
mysqli_stmt_store_result($stmt); // Simpan hasil agar bisa dicek jumlah barisnya
if (mysqli_stmt_num_rows($stmt) == 1) {
mysqli_stmt_bind_result($stmt, $id, $db_username, $hashed_password_from_db, $role);
if (mysqli_stmt_fetch($stmt)) {
// Verifikasi password
if (password_verify($password, $hashed_password_from_db)) {
// Password cocok, login berhasil!
// Simpan data pengguna ke dalam sesi
$_SESSION['user_id'] = $id;
$_SESSION['username'] = $db_username;
$_SESSION['role'] = $role;
// Regenerate session ID untuk keamanan tambahan (mencegah session fixation)
session_regenerate_id(true);
// Redirect ke dashboard admin
header("Location: index.php");
exit;
} else {
$login_error = "Password salah.";
}
}
} else {
$login_error = "Username atau Email tidak ditemukan.";
}
} else {
$login_error = "Oops! Terjadi kesalahan. Silakan coba lagi nanti.";
error_log("Login execute error: " . mysqli_stmt_error($stmt));
}
mysqli_stmt_close($stmt); // Tutup statement
} else {
$login_error = "Oops! Terjadi kesalahan pada persiapan statement. Silakan coba lagi nanti.";
error_log("Login prepare error: " . mysqli_error($conn));
}
}
}
// Tutup koneksi jika sudah tidak digunakan di halaman ini
// mysqli_close($conn); // Sebaiknya ditutup di akhir skrip yang benar-benar selesai menggunakannya
// Set judul halaman (digunakan jika kita membuat header_admin.php)
$page_title_admin = "Login Admin";
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $page_title_admin; ?> - CMS Admin</title>
<link rel="stylesheet" href="../css/admin_style.css"> <!-- CSS khusus admin -->
<!-- Jika tidak ada admin_style.css, bisa link ke style.css utama dan override -->
<!-- <link rel="stylesheet" href="../css/style.css"> -->
<style>
/* Styling minimal untuk halaman login jika admin_style.css belum ada */
body { font-family: Arial, sans-serif; background-color: #f4f4f4; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin:0; }
.login-container { background-color: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 0 15px rgba(0,0,0,0.1); width: 100%; max-width: 400px; }
.login-container h2 { text-align: center; margin-bottom: 20px; color: #333; }
.form-group { margin-bottom: 15px; }
.form-group label { display: block; margin-bottom: 5px; font-weight: bold; }
.form-group input[type="text"], .form-group input[type="password"] { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; }
.login-btn { background-color: #007bff; color: white; padding: 10px 15px; border: none; border-radius: 4px; cursor: pointer; width: 100%; font-size: 16px; }
.login-btn:hover { background-color: #0056b3; }
.error-message { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; padding: 10px; border-radius: 4px; margin-bottom: 15px; text-align: center;}
</style>
</head>
<body>
<div class="login-container">
<h2>Login Administrator</h2>
<?php if (!empty($login_error)): ?>
<p class="error-message"><?php echo htmlspecialchars($login_error); ?></p>
<?php endif; ?>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
<div class="form-group">
<label for="username_or_email">Username atau Email:</label>
<input type="text" name="username_or_email" id="username_or_email" required value="<?php echo isset($_POST['username_or_email']) ? htmlspecialchars($_POST['username_or_email']) : ''; ?>">
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" name="password" id="password" required>
</div>
<button type="submit" class="login-btn">Login</button>
</form>
</div>
</body>
</html>
Penjelasan admin/login.php
:
session_start()
: Harus dipanggil di paling atas setiap halaman yang akan menggunakan sesi.- Redirect jika Sudah Login: Mencegah pengguna yang sudah login mengakses halaman login lagi.
- Koneksi Database: Menggunakan
require_once '../includes/db_connect.php';
karenalogin.php
ada di dalam subfolderadmin
. - Form Handling (
$_SERVER["REQUEST_METHOD"] == "POST"
): Kode di dalamnya hanya dijalankan saat form disubmit. - Prepared Statements (
mysqli_prepare
,mysqli_stmt_bind_param
,mysqli_stmt_execute
, dll.): Ini adalah cara yang sangat direkomendasikan untuk menjalankan query SQL dengan input dari pengguna. Ini membantu mencegah SQL Injection secara signifikan karena query dan data dikirim terpisah ke server database.?
adalah placeholder untuk data."ss"
dimysqli_stmt_bind_param
berarti dua parameter berikutnya adalah string.
password_verify($password, $hashed_password_from_db)
: Membandingkan password yang dimasukkan pengguna dengan hash yang tersimpan di database. Jangan pernah menyimpan password plaintext!- Menyimpan Data ke Sesi: Jika login berhasil,
$_SESSION['user_id']
,$_SESSION['username']
, dan$_SESSION['role']
disimpan. session_regenerate_id(true)
: Mengganti ID sesi saat ini dengan yang baru (dan menghapus yang lama). Ini adalah praktik keamanan yang baik untuk mencegah serangan session fixation.- Form HTML: Formulir login sederhana.
htmlspecialchars($_SERVER["PHP_SELF"])
untuk keamanan pada atributaction
. - Menampilkan Error:
$login_error
digunakan untuk menampilkan pesan jika login gagal. - CSS Sederhana: Menyertakan CSS inline minimal jika
admin_style.css
belum dibuat. Anda sebaiknya membuat../css/admin_style.css
terpisah untuk styling area admin.
Langkah 2: Skrip Otentikasi (admin/auth_check.php
)
Skrip ini akan disertakan di setiap halaman admin (kecuali login.php
) untuk memastikan hanya pengguna yang sudah login yang bisa mengaksesnya.
Buat file admin/auth_check.php
:
<?php
// admin/auth_check.php
// Mulai sesi jika belum dimulai (penting untuk konsistensi)
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
// Periksa apakah pengguna sudah login
if (!isset($_SESSION['user_id'])) {
// Jika belum login, redirect ke halaman login
// Simpan URL yang sedang diakses agar bisa kembali setelah login (opsional)
$_SESSION['redirect_url'] = $_SERVER['REQUEST_URI'];
// Pastikan path ke login.php benar dari lokasi file yang meng-include auth_check.php
// Jika auth_check.php selalu di root admin, maka 'login.php' cukup.
// Jika bisa di-include dari subfolder admin, perlu path yang lebih dinamis atau absolut.
// Untuk struktur kita saat ini, 'login.php' seharusnya bekerja dari file di root admin.
header("Location: login.php");
exit;
}
// (Opsional) Periksa peran pengguna jika halaman memerlukan peran tertentu
// Contoh: hanya 'admin' yang boleh mengakses halaman manajemen pengguna
// if ($_SESSION['role'] !== 'admin' && basename($_SERVER['PHP_SELF']) === 'manage_users.php') {
// echo "Anda tidak memiliki izin untuk mengakses halaman ini.";
// // Atau redirect ke halaman lain, misalnya dashboard
// // header("Location: index.php");
// exit;
// }
// Pengguna sudah login dan (jika ada) memiliki peran yang sesuai.
// Anda bisa mengambil data pengguna dari sesi jika diperlukan di halaman yang meng-include ini.
$current_user_id = $_SESSION['user_id'];
$current_username = $_SESSION['username'];
$current_user_role = $_SESSION['role'];
?>
Penjelasan admin/auth_check.php
:
session_status() == PHP_SESSION_NONE
: Mengecek apakah sesi sudah dimulai. Jika belum,session_start()
dipanggil. Ini berguna jika file ini di-include dari tempat yang mungkin belum memulai sesi.!isset($_SESSION['user_id'])
: Kondisi utama untuk mengecek status login.- Redirect ke Login: Jika tidak login, pengguna diarahkan ke
login.php
. - Menyimpan URL Redirect (Opsional): Menyimpan URL yang sedang coba diakses pengguna ke dalam sesi. Setelah login berhasil, kita bisa mengarahkan pengguna kembali ke URL tersebut. (Implementasi redirect kembali ini akan ada di
login.php
). - Pengecekan Peran (Opsional Lanjutan): Contoh bagaimana Anda bisa membatasi akses ke halaman tertentu berdasarkan peran pengguna.
- Variabel
$current_user_id
,$current_username
,$current_user_role
bisa digunakan di halaman yang meng-include skrip ini.
Modifikasi admin/login.php
untuk menangani redirect URL:
Di admin/login.php
, setelah login berhasil dan sebelum header("Location: index.php");
, tambahkan:
// ... (di dalam blok if password_verify berhasil)
$_SESSION['user_id'] = $id;
$_SESSION['username'] = $db_username;
$_SESSION['role'] = $role;
session_regenerate_id(true);
// Cek apakah ada URL redirect yang disimpan
if (isset($_SESSION['redirect_url'])) {
$redirect_url = $_SESSION['redirect_url'];
unset($_SESSION['redirect_url']); // Hapus dari sesi setelah digunakan
header("Location: " . $redirect_url);
} else {
// Redirect default ke dashboard admin
header("Location: index.php");
}
exit;
// ...
Langkah 3: Dashboard Admin (admin/index.php
)
Ini adalah halaman utama area admin yang akan dilihat pengguna setelah berhasil login.
Buat file admin/index.php
:
<?php
// admin/index.php - Dashboard Admin
// 1. Sertakan skrip otentikasi
require_once 'auth_check.php'; // Ini akan memulai sesi jika belum dan mengecek login
// 2. Sertakan file koneksi jika perlu query database di sini
require_once '../includes/db_connect.php';
// (Opsional) Ambil beberapa statistik dari database
$sql_total_posts = "SELECT COUNT(id) as total_posts FROM posts";
$result_total_posts = mysqli_query($conn, $sql_total_posts);
$total_posts = ($result_total_posts) ? mysqli_fetch_assoc($result_total_posts)['total_posts'] : 0;
$sql_published_posts = "SELECT COUNT(id) as published_posts FROM posts WHERE status = 'published'";
$result_published_posts = mysqli_query($conn, $sql_published_posts);
$published_posts = ($result_published_posts) ? mysqli_fetch_assoc($result_published_posts)['published_posts'] : 0;
// Set judul halaman
$page_title_admin = "Dashboard Admin";
// (Opsional) Sertakan header khusus admin jika ada
// require_once 'includes/header_admin.php';
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($page_title_admin); ?> - CMS Admin</title>
<link rel="stylesheet" href="../css/admin_style.css"> <!-- Atau ../css/style.css jika belum ada admin_style.css -->
<style>
/* Styling minimal untuk dashboard jika admin_style.css belum ada */
body { font-family: Arial, sans-serif; margin: 0; background-color: #f8f9fa; }
.admin-header { background-color: #343a40; color: white; padding: 15px 20px; display: flex; justify-content: space-between; align-items: center; }
.admin-header h1 { margin: 0; font-size: 1.5rem; }
.admin-header a { color: #ffc107; text-decoration: none; }
.admin-header a:hover { text-decoration: underline; }
.admin-container { padding: 20px; }
.welcome-message { margin-bottom: 20px; font-size: 1.2rem; }
.admin-nav ul { list-style: none; padding: 0; margin: 0 0 20px 0; display: flex; gap: 10px; }
.admin-nav ul li a { display: block; padding: 10px 15px; background-color: #007bff; color: white; text-decoration: none; border-radius: 4px; }
.admin-nav ul li a:hover { background-color: #0056b3; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-bottom: 20px; }
.stat-card { background-color: white; padding: 20px; border-radius: 5px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); text-align: center; }
.stat-card h3 { margin-top: 0; color: #007bff; }
.stat-card p { font-size: 1.8rem; font-weight: bold; margin-bottom: 0; }
</style>
</head>
<body>
<header class="admin-header">
<h1>Admin Panel</h1>
<div>
Selamat datang, <?php echo htmlspecialchars($current_username); ?> (<?php echo htmlspecialchars($current_user_role); ?>) |
<a href="logout.php">Logout</a>
</div>
</header>
<div class="admin-container">
<p class="welcome-message">Selamat datang di Dashboard Admin!</p>
<nav class="admin-nav">
<ul>
<li><a href="index.php">Dashboard</a></li>
<li><a href="manage_posts.php">Kelola Artikel</a></li> <!-- Akan dibuat di Part 3 -->
<li><a href="manage_categories.php">Kelola Kategori</a></li> <!-- Akan dibuat di Part 4 -->
<?php if ($current_user_role === 'admin'): // Hanya admin yang bisa kelola user ?>
<li><a href="manage_users.php">Kelola Pengguna</a></li> <!-- Akan dibuat di Part 5 -->
<?php endif; ?>
<li><a href="../index.php" target="_blank">Lihat Situs</a></li>
</ul>
</nav>
<h2>Statistik Situs</h2>
<div class="stats-grid">
<div class="stat-card">
<h3>Total Artikel</h3>
<p><?php echo $total_posts; ?></p>
</div>
<div class="stat-card">
<h3>Artikel Terbit</h3>
<p><?php echo $published_posts; ?></p>
</div>
<!-- Tambahkan statistik lain jika perlu -->
</div>
<p>Dari sini Anda dapat mengelola berbagai aspek dari situs web Anda.</p>
</div>
<?php
// (Opsional) Sertakan footer khusus admin jika ada
// require_once 'includes/footer_admin.php';
// Tutup koneksi database
if (isset($conn)) {
mysqli_close($conn);
}
?>
</body>
</html>
Penjelasan admin/index.php
:
require_once 'auth_check.php';
: Baris pertama yang sangat penting. Jika pengguna tidak login, mereka akan diarahkan kelogin.php
sebelum kode lain di halaman ini dieksekusi.- Menampilkan Informasi Pengguna: Menggunakan variabel
$current_username
dan$current_user_role
yang didefinisikan diauth_check.php
. - Navigasi Admin: Link ke berbagai bagian manajemen (artikel, kategori, pengguna) yang akan kita buat di bagian selanjutnya.
- Statistik Sederhana: Contoh mengambil data agregat dari database untuk ditampilkan.
- Link “Lihat Situs”: Membuka frontend di tab baru.
- Kondisional Navigasi untuk Admin: Menu “Kelola Pengguna” hanya muncul jika peran pengguna adalah
admin
.
Langkah 4: Skrip Logout (admin/logout.php
)
Skrip ini akan menghancurkan sesi dan mengarahkan pengguna kembali ke halaman login atau halaman utama situs.
Buat file admin/logout.php
:
<?php
// admin/logout.php
// Mulai sesi
session_start();
// Hapus semua variabel sesi
$_SESSION = array(); // Atau session_unset();
// Hancurkan sesi
if (session_destroy()) {
// Jika sesi berhasil dihancurkan, redirect ke halaman login
// Anda juga bisa mengarahkan ke halaman utama situs (../index.php)
header("Location: login.php?status=loggedout");
exit;
} else {
// Jika ada masalah saat menghancurkan sesi (jarang terjadi)
echo "Error: Tidak bisa logout. Silakan coba lagi.";
// Mungkin log error di sini
exit;
}
?>
Penjelasan admin/logout.php
:
$_SESSION = array();
atausession_unset();
: Menghapus semua data yang tersimpan dalam variabel$_SESSION
.session_destroy()
: Menghancurkan sesi itu sendiri di server.- Redirect: Setelah logout, pengguna diarahkan. Parameter
?status=loggedout
bisa digunakan dilogin.php
untuk menampilkan pesan “Anda telah berhasil logout”.
Modifikasi admin/login.php
untuk menampilkan pesan logout (opsional):
Di admin/login.php
, di atas form, tambahkan:
// ... (setelah tag <body> atau di dalam .login-container)
<?php if (isset($_GET['status']) && $_GET['status'] == 'loggedout'): ?>
<p class="success-message">Anda telah berhasil logout.</p>
<!-- Tambahkan CSS untuk .success-message jika perlu -->
<?php endif; ?>
// ...
Langkah 5: Membuat CSS Khusus Admin (../css/admin_style.css
) - Opsional
Untuk tampilan area admin yang berbeda dan lebih terorganisir, sebaiknya buat file CSS terpisah.
Buat file css/admin_style.css
(di luar folder admin
, di dalam folder css
utama):
/* css/admin_style.css */
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
background-color: #eef1f5; /* Latar belakang admin yang berbeda */
color: #333;
font-size: 15px;
}
.admin-header {
background-color: #2c3e50; /* Warna header admin */
color: #ecf0f1;
padding: 15px 30px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.admin-header h1 {
margin: 0;
font-size: 1.6rem;
}
.admin-header .user-info a {
color: #f1c40f; /* Warna link logout */
text-decoration: none;
margin-left: 10px;
}
.admin-header .user-info a:hover {
text-decoration: underline;
}
.admin-container {
padding: 25px;
max-width: 1200px; /* Kontainer lebih lebar untuk admin */
margin: 20px auto;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.05);
}
.welcome-message {
font-size: 1.3rem;
color: #2c3e50;
margin-bottom: 25px;
border-bottom: 1px solid #ddd;
padding-bottom: 15px;
}
.admin-nav {
margin-bottom: 30px;
}
.admin-nav ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-wrap: wrap; /* Agar wrap di layar kecil */
gap: 15px; /* Jarak antar tombol nav */
}
.admin-nav ul li a {
display: block;
padding: 12px 20px;
background-color: #3498db; /* Warna tombol navigasi admin */
color: white;
text-decoration: none;
border-radius: 5px;
font-weight: 500;
transition: background-color 0.2s ease;
}
.admin-nav ul li a:hover,
.admin-nav ul li a.active { /* Kelas .active bisa ditambahkan dengan PHP */
background-color: #2980b9; /* Warna hover */
}
.admin-container h2 {
font-size: 1.5rem;
color: #2c3e50;
margin-top: 30px;
margin-bottom: 20px;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 25px;
margin-bottom: 30px;
}
.stat-card {
background-color: #f8f9fa; /* Warna kartu stat sedikit beda */
padding: 25px;
border-radius: 6px;
border: 1px solid #dee2e6;
text-align: center;
}
.stat-card h3 {
margin-top: 0;
margin-bottom: 10px;
font-size: 1.1rem;
color: #3498db;
}
.stat-card p {
font-size: 2.2rem;
font-weight: bold;
color: #2c3e50;
margin-bottom: 0;
}
/* Styling untuk form login (jika menggunakan admin_style.css) */
.login-container {
background-color: #fff;
padding: 40px;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0,0,0,0.15);
width: 100%;
max-width: 420px;
margin: 50px auto; /* Tengahkan jika halaman login punya header/footer admin */
}
/* ... (lanjutkan styling form login dari inline style sebelumnya jika perlu) ... */
.error-message, .success-message { /* Untuk login.php */
padding: 12px 15px;
border-radius: 4px;
margin-bottom: 20px;
text-align: center;
font-weight: 500;
}
.error-message { background-color: #e74c3c; color: white; }
.success-message { background-color: #2ecc71; color: white; }
Pastikan link ke admin_style.css
di admin/login.php
dan admin/index.php
sudah benar (../css/admin_style.css
).
Menguji Area Admin
- Coba Akses Dashboard Langsung: Buka browser dan coba akses
http://localhost/cms_sederhana_project/admin/index.php
. Anda seharusnya diarahkan ke halamanlogin.php
karena belum login. - Login dengan Kredensial Salah: Coba login dengan username atau password yang salah. Anda seharusnya melihat pesan error.
- Login dengan Kredensial Benar: Gunakan username (
admin
) dan password (admin123
atau yang Anda set) yang benar. Anda seharusnya diarahkan keadmin/index.php
(Dashboard Admin). - Periksa Informasi Pengguna: Di dashboard, pastikan nama pengguna dan peran ditampilkan dengan benar.
- Coba Logout: Klik link “Logout”. Anda seharusnya diarahkan kembali ke halaman login, idealnya dengan pesan “Anda telah berhasil logout”.
- Akses Setelah Logout: Setelah logout, coba akses lagi
admin/index.php
. Anda harus diarahkan kembali ke login.
Refleksi Part 2 dan Apa Selanjutnya?
Luar biasa! Di Bagian 2 ini, kita telah berhasil membangun inti dari area admin: sistem login yang aman dengan hashing password dan sesi PHP, serta halaman dashboard dasar yang dilindungi. Ini adalah langkah krusial untuk mengelola CMS kita.
Poin Kunci yang Telah Dicapai:
- Pembuatan tabel
users
dengan password yang di-hash. - Formulir login dengan validasi dan verifikasi password.
- Penggunaan sesi PHP untuk manajemen login.
- Skrip otentikasi untuk melindungi halaman admin.
- Halaman dashboard admin sederhana dan mekanisme logout.
- Penggunaan prepared statements untuk keamanan query.
Di Part 3 dari seri ini, kita akan mulai menambahkan fungsionalitas inti CMS ke area admin, yaitu Manajemen Artikel (CRUD - Create, Read, Update, Delete). Kita akan membuat halaman untuk menambah, melihat daftar, mengedit, dan menghapus postingan artikel.
Pastikan Anda memahami bagaimana sesi, hashing, dan perlindungan halaman bekerja, karena ini akan terus kita gunakan. Sampai jumpa di bagian berikutnya!