Navigation & Login

Sessions and Server-Side Redirect (Part 2)

Prelude

Requires the lessons up to and including Navigation & Login Part 1 to have been completed
  • Our login technically works but lacks persistence

  • We’ll investigate $_SESSION and $_COOKIE (emphasis on $_SESSION)

    • These are magic variables populated by PHP based on context

  • Make sure you have Feat-MS1-BasicNav-Login active before proceeding

    • If not, git checkout Feat-MS1-BasicNav-Login

  • Checkpoint (if needed):

    • From this link Feat-MS1-BasicNav-Login-Part1, grab the following files:

      • public_html/project/register.php

      • public_html/project/login.php

      • lib/functions.php

      • partials/nav.php

Adding Session Magic

  • Modify nav.php by adding cookie parameters before require():

    • We’ll use session_set_cookie_params()

    • Then we’ll start the session with session_start()

The sub-sections will explain session_set_cookie_params() and session_start() in more detail
<?php
// checking to see if domain has a port number attached (localhost)
$domain = $_SERVER["HTTP_HOST"];
if (strpos($domain, ":")) {
    // strip the port number if present
    $domain = explode(":", $domain)[0];
}
// used for public hosting like heroku/render.com
if ($domain != "localhost") {
    session_set_cookie_params([
        "lifetime" => 60 * 60, // this is cookie lifetime, not session lifetime
        "path" => "/project", // path to restrict cookie to; match your project folder (case sensitive)
        "domain" => $domain, // domain to restrict cookie to
        "secure" => true, // https only
        "httponly" => true, // javascript can't access
        "samesite" => "lax" // helps prevent CSRF, but allows normal navigation
    ]);
}
session_start();
require(__DIR__."/../lib/functions.php");

session_start()

  • session_start() tells PHP to find/create a session based on PHPSESSID cookie

    • This is required for sessions to work properly

  • Sessions are stored server-side, and the session ID is stored in a cookie

    • Whoever has the cookie or id will have access to the session instance (hence the importance of httponly and secure)

  • Default session timeout: 24 minutes (but Heroku/Render.com destroys sessions on sleep/restart)

    • Additionally, deleting the cookie would lose the id that links to the session but the session would still be active session cookie 2

On Heroku or Render.com, or a deployed environment, you’d see the correct path instead of just /

A cookie is a small piece of data stored on the client-side, while a session is a server-side storage mechanism that can be accessed via a unique identifier (session ID) stored in a cookie.

Proof of Concept Part 1

Always escape user data before outputting it to prevent XSS, even if you trust your session data

If you test this now, you’ll likely see "Not logged in", even if you tried logging in

Proof of Concept Part 2

Server-Side Redirects

  • You may notice we’re currently "stuck" sitting at the login page after we login

  • Let’s have the app redirect us upon success

  • Use header() for navigation control

    • There are more uses for this, but we’ll set the Location: header which tells the browser to redirect somewhere

    • Other uses: caching behavior, downloads, etc

    • Add the following after setting the $_SESSION["user"] in login.php

header("Location: landing.php");
die(); // stop script execution after header
// or as a single line
die(header("Location: landing.php"))
  • This prevents further code execution after redirection which is necessary in certain scenarios

  • Try to login again and notice the difference

header() must be called before any output is sent to the browser, including whitespace. If you see a "headers already sent" error, check for any output before the header() call. In future lessons, we’ll explore how to handle this more gracefully.

Logout

  • Lastly, we need a way to gracefully destroy the session

  • In the project folder create logout.php:

<?php
session_start(); // starts/gets the active session
session_unset(); // good practice to clear session variables
session_destroy(); // destroys the session on the server
header("Location: login.php"); // redirect back to login
  • Since this is an intermediary file (not something a user will stay on) we won’t require nav.php

  • It’ll start the session so we have access to it, then unset/destroy the session data and redirect back to login.php

  • Generally it’d be a good idea to delete the cookie too, but not mandatory as it’ll eventually expire

  • Trying logging out after you’ve logged in, then visit landing.php manually to confirm

Summary

  • We now have a basic registration, login, and logout system

  • Make sure you understand session behavior with $_SESSION and session_start()

  • Push changes to Feat-MS1-BasicNav-Login and merge to Milestone1 via a Pull Request

    • git add .

    • git commit -m "add basic navigation and login functionality"

    • git push origin Feat-MS1-BasicNav-Login

    • Don’t forget to locally checkout Milestone1 and pull changes to be ready for the next topics

      • git checkout Milestone1

      • git pull origin Milestone1

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

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