====== 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** 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'); ?>

**header.php** Tech School

Tech School Web Development Course

**menu.php** ==== 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. * 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'.

* 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. * 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. * 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'. [[en:web_development:sessions:exercises|Next: Exercises]]