Aim
To create an admin login and logout system in PHP where the logged-in state and the admin's details are held in session variables.
Theory
Because HTTP is stateless, "being logged in" must be remembered somewhere across requests. The server-side answer is the session: session_start() (called before any output) creates or resumes a per-visitor data store, the browser holds only the random session ID in the PHPSESSID cookie, and $_SESSION exposes the stored data as an array.
The standard authentication pattern has three parts. Login: verify the credentials, then record the fact — $_SESSION["logged_in"] = true plus any details worth caching (name, role, login time). Guarding: every protected page starts the session and checks the flag — if (empty($_SESSION["logged_in"])) { header("Location: login.php"); exit; } — so typing an admin URL directly cannot skip the login. Logout: session_unset() empties the array and session_destroy() deletes the server-side record, making the old ID worthless. Production code also calls session_regenerate_id(true) right after login to defeat session fixation.
Requirements
- XAMPP/WAMP with Apache and PHP 8.x
- Code editor (VS Code)
- Browser (Chrome/Edge) — the form must be POSTed, so run it under Apache, not the CLI
Procedure
- Start Apache from the XAMPP Control Panel.
- Save the snippet as
p16_admin_session.phpinC:\xampp\htdocs\wbplab. - Open
http://localhost/wbplab/p16_admin_session.php— the Admin Login form appears. - Submit a wrong pair (red error), then
rohit/rohit@123— the dashboard shows the stored session values; click Logout to return to the form. - The snippet's first line is an array shim instead of
session_start(), so the file also runs in online compilers that have no cookie round-trip; under Apache, swap in thesession_status()guard from Practical 12 and the login survives refreshes and new tabs.
Explanation of the Code
if (!isset($_SESSION)) { $_SESSION = []; }guarantees the superglobal exists in any environment; with a realsession_start()the very same reads and writes would persist across requests.- The admin identity is fixed with
define()constants;ADMIN_HASHstores apassword_hash()ofrohit@123, later checked withpassword_verify()— no plain-text comparison. - The login branch fires on POST plus
isset($_POST["login"]): on success it fills five session keys —logged_in,admin_user,admin_email,login_time(viadate("Y-m-d H:i:s")) androle— otherwise it setsInvalid username or password. elseif (isset($_POST["logout"]))is the server-side logout path, resetting$_SESSION = []. The rendered Logout button, though, calls the JavaScriptdoLogout()toggle — to exercise the PHP branch it would have to sit in a<form method="POST">as a button namedlogout.$isLoggedIn = !empty($_SESSION["logged_in"])drives the$dashDisplay/$loginDisplayternaries; each dashboard row echoes its session value throughhtmlspecialchars(), with an$isLoggedIn ? … : ""guard so no undefined-key warnings appear while logged out.
Expected Output
First load shows the Admin Login form. A wrong pair re-renders it with the red Invalid username or password. Entering rohit / rohit@123 swaps in the grey 🔒 Admin Dashboard panel listing User: rohit, Email: rohit@example.com, Role: admin and Since: with the exact login timestamp. Clicking Logout flips back to the login form topped by the green ✓ Logged out successfully. message.
🎯 Viva Questions
- Why must the logged-in flag live in a session rather than a cookie? Cookies are client-side and user-editable — anyone could set
role=admin; session data stays on the server and the client holds only the ID. - Which two calls make a complete logout?
session_unset()to clear$_SESSION, thensession_destroy()to delete the server-side record. - What is the guard pattern for a protected page? Start the session, then
if (empty($_SESSION["logged_in"]))redirect to the login page andexit— theexitmatters, or the protected body still renders. - What is session fixation and its remedy? An attacker pre-plants a known session ID and waits for the victim to log in under it; calling
session_regenerate_id(true)after login issues a fresh ID. - Why does this snippet's login not survive a page refresh as written? It never calls
session_start(), so the shimmed$_SESSIONarray lives only for the current request; addingsession_start()restores real persistence. - What exactly is stored in the
PHPSESSIDcookie? Only the random session identifier — never the data itself; the server uses it to reload that visitor's$_SESSIONon the next request.
CO Mapping
CO1, CO2