Navigation & Login

Authentication (Part 1)

Prerequisite

  • Requires the lessons up to and including User Registration Part 2 to have been completed

  • Checkout Milestone1 locally

    • git checkout Milestone1

  • Pull any pending changes

    • git pull origin Milestone1

  • Create a new branch Feat-MS1-BasicNav-Login

    • git checkout -b Feat-MS1-BasicNav-Login

Navigation

  • Before working on login, we’ll create a simple way to navigate around the site

  • Create a nav.php file in the partials folder and add the following content

    • This file will be included on every page that needs navigation via require()

<?php
require(__DIR__."/../lib/functions.php"); (1)
?>
<nav> (2)
    <ul>
        <li><a href="login.php">Login</a></li>
        <li><a href="register.php">Register</a></li>
        <li><a href="logout.php">Logout</a></li>
    </ul>
</nav>
1This will ensure that the functions are available on any page that includes this nav (Note: _DIR_ is used to get the current directory of the file, which helps avoid path issues)
2This is a simple navigation bar with links to login, register, and logout pages
All pages that require nav.php should not require functions.php or db.php directly, as they will be included automatically through nav.php.

Update Register.php

  • Update register.php

    • Change the require statement at the top of the page to:

require(__DIR__ . "/../../partials/nav.php");
  • Ensure only one require() is used to prevent duplicate inclusion issues

  • The page will now have access to the functions and database via the nav.php

nav.php includes functions.php, so you don’t need to include it again in register.php. This is a common practice to avoid redundancy and potential errors.

Login

  • Create a new file called login.php in the project folder

  • Copy the content from register.php and remove all references to "confirm" password

  • Update the heading to "Login"

  • Update the submit button to say "Login"

  • Modify the else block to remove everything except for TODO 4

  • The login process will be added in TODO 4 to handle the action

Handling Login

  • Insert the following code under TODO 4 in login.php

if (!$hasError) {
    //TODO 4: Check password and fetch user
    $db = getDB(); (1)
    $stmt = $db->prepare("SELECT id, email, password from Users where email = :email"); (2)
    try {
        $r = $stmt->execute([":email" => $email]); (3)
        if ($r) {
            $user = $stmt->fetch(PDO::FETCH_ASSOC); (4)
            if ($user) {
                $hash = $user["password"];
                unset($user["password"]); (5)
                if (password_verify($password, $hash)) { (6)
                    echo "Welcome, $email!<br>";
                } else {
                    echo "Invalid password<br>";
                }
            } else {
                echo "Email not found<br>"; (7)
            }
        }
    } catch (Exception $e) {
        echo "There was an error logging in<br>"; // user-friendly message
        error_log("Login Error: " . var_export($e, true)); // log the technical error for debugging
    }
}
1Gets the database connection from getDB(), which is available due to the require() of nav.php
2Prepares a statement to select the user by email (uses named placeholders; this prevents SQL injection)
3Executes the prepared statement with the provided email
4Fetches the user data as an associative array
5Unsets the password from the user array to prevent accidental exposure
6Uses password_verify() to check if the provided password matches the hashed password from the database
7Informs the user that the email does not exist (this is bad practice since it reveals information about the existence of the email; leads to user enumeration attacks; we’ll address this in the future)
password_verify() is a secure way to check passwords against their hashes. It automatically handles the salt and hashing algorithm, making it safe to use without needing to manage these details manually. Counter part to password_hash() which is used during registration to create the hash.

Summary

  • Added a basic navigation bar for switching between registration and login

    • Haven’t implemented logout yet

  • The user’s session is not yet persistent, and they will lose the login state upon refreshing or leaving the page

  • Add/Commit these changes to the Feat-MS1-BasicNav-Login branch

    • git add .

    • git commit -m "basic nav and login part 1"

  • You can push to GitHub now or wait until Part 2

    • git push origin Feat-MS1-BasicNav-Login

  • Checkpoint: https://github.com/MattToegel/IT202-2025/tree/Module04-Login-Part1

    • Note: My branch name differs from yours so I can isolate the lesson content

  • In the next steps, we’ll learn about sessions and how to manage user navigation