User Tools

Site Tools


en:web_development:sessions:sessions

Web Development Lesson 9 - Sessions

Sessions

Objective

In this activity you'll create a session and recover the session on each page.

Setup

  • We'll continue to use 'login.php', 'header.php' and 'menu.php' so here they are again in case you need them.

login.php

<?php
    include ('database.php');

    error_log("MURRAY: " . print_r($_POST,1));
    if ($_POST['formSubmit'] == 'register') {
        $name     = $_POST['username'];
        $email    = $_POST['email'];
        $password = $_POST['password'];
        $confirm  = $_POST['confirm'];

        // check data in all fields
        $message = "";
        if (($name == "") || ($email == "") || ($password == "") || ($confirm == "")) {
            $message .= "Please complete all required fields. ";
        }
        
        // check email format
        if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $message .= "Please enter a valid email address. ";
        }

        // check if email exists
        $query = "SELECT * FROM users WHERE email=?";
        $args  = array($email);
        $rslt  = $pdo->prepare($query);
        $rslt->execute($args);
        if ($row = $rslt->fetch()) {
            $message .= "You already have an account. ";
        }

        // check passwords match
        if ($password != $confirm) {
            $message .= "Please ensure passwords match. ";
        }

        // process registration
        if ($message == "") {
            // hash password to make it secure
            $hash  = password_hash ($password, PASSWORD_BCRYPT);
            // add user
            $query = "INSERT INTO users (username, email, password) VALUES (?,?,?)";
            $args  = array($name, $email, $hash);
            $rslt  = $pdo->prepare($query);
            if ($rslt->execute($args)) {
                $message = "Your account has been created. Please log in.";
            } else {
                $message = "There was a problem adding your account.";
            }
        }
    } else if ($_POST['formSubmit'] == 'login') {
        $name     = $_POST['username'];
        $password = $_POST['password'];

        // check data in all fields
        $message = "";
        if (($name == "") || ($password == "")) {
            $message .= "Please complete all required fields. ";
        }

        // process login
        if ($message == "") {
            // check for user in database
            $query = "SELECT id, password FROM users WHERE username=?";
            $args  = array($name);
            $rslt  = $pdo->prepare($query);
            $rslt->execute($args);
            if ($row = $rslt->fetch()) {
                // user exists
                $hash = $row['password'];
				if (password_verify($password, $hash)) { // password matches
                    // create session
                    error_log('logged in');
                } else {
                    $message = "That password is incorrect. Please try again.";
                }
            } else {
                $message = "That user does not exist. Please try again.";
            }
        }
    }

    $page = "login";
    include('header.php');
?>
    <main>
        <div id="status">
            <p><?php echo $message; ?></p>
        </div>
        <form name="loginForm" action="login.php" method="post">
            <fieldset>
                <ul>
                    <li>
                        <label for="username">User Name:<span class="required">*</span></label>
                        <input type="text" name="username">
                    </li>
                    <li class="register">
                        <label for="email">Email:<span class="required">*</span></label>
                        <input type="email" name="email">
                    </li>
                    <li>
                        <label for="password">Password:<span class="required">*</span></label>
                        <input type="password" name="password">
                    </li>
                    <li class="register">
                        <label for="confirm">Confirm Password:<span class="required">*</span></label>
                        <input type="password" name="confirm">
                    </li>
                </ul>
                <input type="hidden" name="formSubmit" value="">
                <input type="button" name="login" value="Log In" onclick="loginUser()">
                <input class="register" type="button" name="register" value="Register" onclick="registerUser()">
            </fieldset>
        </form>
    </main>
<?php
    include('footer.php');
?>

header.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tech School</title>
    <link rel="stylesheet" href="style.css">
    <script src="<?php echo $page; ?>.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
    <header>
        <h1>Tech School Web Development Course</h1>
    </header>

menu.php

<nav>
    <ul>
        <li><a href="lists.php">Lists</a></li>
        <li><a href="tables.php">Tables</a></li>
        <li><a href="layout.php">Layout</a></li>
        <li><a href="media.php">Media</a></li>
        <li><a href="mysql.php">Databases</a></li>
        <li><a href="form.php">Forms</a></li>
        <li><a href="login.php">Login</a></li>
        <li><a href="logout.php">Logout</a></li>
    </ul>
</nav>

Create Session

  • A session is a communication flow between a user and a site.
  • They can be short to ensure security or they can be indefinite to keep details used for advertising (for example).
  • The server keeps information on the user, which pages they've been to etc in a 'session variable'.
  • The user keeps some of this information, including the 'session id' on their computer / phone in the form of 'cookies'.
  • The cookie must be sent to the user's browser before any other code, which means it must be done before we call include('header.php').
  • Add the following code under //create session in 'login.php'
                    session_start();
                    unset($_SESSION['profile']);
                    session_set_cookie_params(array('SameSite' => 'strict'));
                    $_SESSION['profile'] = array('id' => $row['id'], 'name' => $name);
  • The first line sets up the session between the browser and the server.
  • The second line deletes any previous session. Since the user is logging in, we want to ensure we're starting from scratch.
  • The third line stops cookies from being shared with other sites.
  • The last line creates our session information with an array called 'profile' containing the database id and the user name.
  • We could add other arrays to our session like pages visited or items bought, but we don't need those here.
  • Let's also check the profile session information.
                    error_log("MURRAY: " . print_r($_SESSION['profile'], 1));
  • Save, upload and login, then check your PHP logs to see whether the session information is there.

PHP Redirect

  • When the user is logged in and the session has been created, they no longer need to see the login page.
  • Let's redirect them to 'form.php'.
                    header("Location: form.php");
  • This will tell the browser to open the page 'form.php'.
  • You can also add a full URL such as header("Location: http://google.com"); but for pages on the same site, the relative address is usually simpler.
  • Save, upload and try this.
  • If you've set everything up properly, you should be sent to 'form.php' as soon as you log in.

Loading Sessions

  • 'form.php' doesn't yet have the details of the session.
  • Just as we started the session in 'login.php', we need to do the same in 'header.php'.
  • We use 'header.php' because it's called at the start of every page so we only need to do it in one place to make it work for all pages.
<?php
    session_start();
?>
<!DOCTYPE html>
  • With the session started, we can check the information we stored in 'login.php'.
    error_log("MURRAY 'form.php': " . print_r($_SESSION['profile'], 1));
  • Save, upload and load the page.
  • Your logs should include the new line with the details of your login.
  • Let's display this in the sidebar menu. Add this code before the list in 'menu.php'.
    <h2><?php echo $_SESSION['profile']['name']; ?></h2>
  • Save, upload and load 'form.php' again.
  • You should see your user name at the top left of the menu.
  • We can align it better by adding some padding to the left. Add this code (and any other styling you like) to 'style.css'.
h2 {
  padding-left: 40px;
}

Ending Sessions

  • What happens if a user tries to load the form without having logged in?
  • To test that, we first need to log out.
  • Create a file called 'logout.php' and add the following code.
<?php
    session_start();
    unset($_SESSION['profile']);
    header("Location: login.php");
?>
  • session_start() starts the session so we have access to the session data.
  • unset deletes the session data so it won't be there when other pages try to access it.
  • The third line sends the user back to the login page.
  • Add 'login.php' and 'logout.php' to the menu.
<nav>
    <h2><?php echo $_SESSION['profile']['name']; ?></h2>
    <ul>
        <li><a href="lists.php">Lists</a></li>
        <li><a href="tables.php">Tables</a></li>
        <li><a href="layout.php">Layout</a></li>
        <li><a href="media.php">Media</a></li>
        <li><a href="mysql.php">Databases</a></li>
        <li><a href="form.php">Forms</a></li>
        <li><a href="login.php">Login</a></li>
        <li><a href="logout.php">Logout</a></li>
    </ul>
</nav>
  • Save and upload all the changed files.
  • Click on 'Log out' and check that you are returned to the login page.
  • Now, without logging in, change the filename in the url to 'form.php' and press enter.
  • You should see the form, but your user name is missing from the top of the menu because you aren't logged in.

Getting Current Filename

  • Now we want to redirect any user that hasn't logged in back to the login page automatically.
  • Add the following code at the end of the PHP block in 'header.php'.
    if (!isset($_SESSION['profile'])) {
        header("Location:login.php");
    }
  • Save and upload the code, then refresh 'form.php'.
  • You should get an error saying that the page is in a redirect loop that will never end.
  • This is because 'login.php' also includes 'header.php' and because the user isn't logged in when the page loads, it will keep being redirected to itself.
  • To avoid this, we can hard code the HTML from 'header.php' into 'login.php', but this means updating any changes to the header twice.
  • Instead, we can check which file is being viewed and if it's 'login.php' we disable the redirect.
  • Add this code after session_start(); in 'header.php'.
    $filename = basename($_SERVER['REQUEST_URI'], '?' . $_SERVER['QUERY_STRING']);
    error_log("MURRAY: " . $filename);
  • $_SERVER['REQUEST_URI'] is the full string entered into the address bar of the browser.
  • $_SERVER['QUERY_STRING'] is everything in the address bar after '?'.
  • basename takes a URL and returns everything from the filename on. By adding '?' . $_SERVER['QUERY_STRING'] as a parameter, we're telling it to exclude the '?' and everything afterwards.
  • Change my name for yours in the error_log.
  • Save and upload the code and try loading 'login.php' again.
  • You'll still get the error, but now you can look at the PHP logs and see the filename ending in '.php'.
  • Now we can add a condition before our redirect. We want to redirect only if the we're not on 'login.php' AND the user is not logged in.
  • Update the code accordingly.
    if (($filename != 'login.php') && !isset($_SESSION['profile'])) {
        header("Location:login.php");
    }
  • Save and upload the code, then make sure it all works correctly.
    • If you're not logged in, you should be redirected to 'login.php' no matter which page you open.
    • If you are logged in, you should be able to open 'form.php' (or any other page except 'login.php') and see your user name above the menu.
    • If you navigate to 'logout.php' you should be redirected to 'login.php'.

Next: Exercises

en/web_development/sessions/sessions.txt · Last modified: 2023/08/16 09:33 (external edit)