====== 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]]