11. Keeping Data Across Pages

What We Will Cover


Elucidations

Homework Questions?

Quiz Questions?

Questions from last class?

11.1: Storing Data in the Browser

Learner Outcomes

At the end of the lesson the student will be able to:

  • Use query strings with PHP
  • Use hidden fields with PHP
  • Make a cookie
  • Extract data from a cookie

11.1.1: Keeping State

  • So far we have considered how to work with only one web page at a time
  • However, some applications need to use the result of one page when processing another
  • For instance, we may display products on one or more catalog pages
  • The user may select an item to place in their shopping cart
  • The item placed in the shopping cart must be remembered when it is time to make the purchase
  • In other words, we need to keep track of the data from one client request to another
  • Keeping track of data from one page to the next is known as keeping state

Why Keeping State is Difficult

  • Keeping track of data from one page to another is surprisingly difficult.
  • This is because HTTP is a stateless protocol.
  • Once a server responds to a request, it drops the connection to the browser.
  • You can see this in the following diagram:

keeping state

How to Keep State

  • There are two ways to keep track of data (state) between multiple pages:
    1. Use the browser to hold the data
    2. Use the server to hold the data
  • In this section, we consider how to use the browser to hold the data
  • In the next section, we discuss how store the data on the server

11.1.2: Using Query Strings

  • A query string is the part of a URL that contains data to be passed to web applications
  • The information appears as part of the URL
  • You can use query strings to pass parameters to a PHP script
  • Whenever necessary, you can code variables that provide the values of the parameters in the URL
  • These variables are often referred to as "CGI variables" or "request variables"
  • The syntax for query strings:
    url?name1=value1&name2=value2&...
    

Query String Examples

  • Here is an example using a hyperlink:
    <a href="cart.php?pid=12345">Add To Cart</a>
    
  • Another way is to add information to the action attribute of a form:
    <form action="cart.php?pid=12345" method="post">
    
  • Also, you can add information to a redirect:
    redirect("cart.php?pid=12345");
    

Limitations of Query Strings

  • Most browsers limit the number of characters that can be passed by a URL to 2,000 characters.
  • Also, all variables are visible in the browser's URL field.
  • If a user creates a bookmark for a page that uses query strings, the parameters for the page are included in the bookmark, which usually isn't what you want.
  • You have to use substitute special characters for characters such as whitespace and the ? and & characters.

More Information

11.1.3: Using Hidden Fields

  • Hidden fields are not part of the PHP language
    • Neither are they part of the Mrs. Fields Cookie Company
  • Instead, they are HTML form elements that the browser does not display
  • You can use hidden fields to pass information without displaying it to a user
  • The receiving PHP script can use the information like any other form element

Creating Hidden Fields

  • Example of a hidden field:
    <input type="hidden" name="pid" value="12345">
    
  • The type="hidden" says to create a hidden field
  • The name attribute provides the variable name for the receiving script
  • The value attribute is the data the receiving script will get for the name

Hidden But Not Invisible

  • Hidden fields are hidden but not completely invisible to the user
  • A user can view them by examining the HTML source
  • For this reason, do not store any data in a hidden field you do not want a user to see

For Example

  • First we create a form with a hidden value:

<?php

main
("Hidden Data");

function 
main($title "") {
    include(
"includes/header.php");
    
showContent($title);
    include(
"includes/footer.php");
}

function 
showContent($title) {
    echo<<<HTML
<h1>$title</h1>
<form action="hiddenecho.php" method="POST">
<input type="hidden" name="secret" value="1234">
<input name="submit" type="submit" value="View">
</form>

HTML;
}
?>

Try it and view the source.

  • Then we create a script to read the hidden value

<?php
main
("Hidden Data Revealed");

function 
main($title "") {
    include(
"includes/header.php");
    
showContent($title);
    include(
"includes/footer.php");
}

function 
showContent($title) {
    echo 
"<h1>$title</h1>\n";
    echo 
"<p>Secret value: ";
    echo 
$_POST['secret']."</p>\n";
}
?>

11.1.4: Introduction to Cookies

  • A more versatile technique than query strings and hidden fields is cookies
  • Cookies are small pieces of text sent to a user's Web browser
  • The Web browser stores the cookies on the user's computer
  • Though originally invented by Netscape, they are supported by most browsers

Why Cookies?

  • Web pages generally do not know anything about the person requesting a page
  • However, you can store any information a user is willing to give you
  • For instance, you may ask a user to login to view a page
  • When the user logs in, you might store a cookie designed to say:

    "This is Ed and Ed is allowed to be here"

  • Now when the user clicks on a page of your site, you can say,"Hello Ed!"

How Cookies Work

  • Cookies request a Web browser to store a little data on the user's computer
  • The data is automatically sent back to the server when a user requests a page from the site that set the cookie

Cookie Flow

Are Cookies a Security Risk?

  • Since a cookie is nothing more than text, it cannot do some things
    • Cannot read or write a file
    • Cannot format a hard disk
    • Cannot send e-mail
    • Cannot generate popups
    • Practically impossible to transmit a virus
  • The real risk of cookies is that someone other than the user might read the cookie data
  • For instance, a person might order a product at a public computer
  • As a service to the user, you might be tempted to store a users login and password to make it easier for returning users
  • However, another person can use the public computer and look at the cookie files
  • Also, it is possible for attackers to examine or steal cookies without physical access to a computer
  • As a designer, you should not store private or sensitive data in a cookie
  • If you must store sensitive data, then make sure you encrypt it first

More Information

11.1.5: Making Cookies

  • When making cookies, you must set them before sending any HTML/text data to the browser
  • If you forget and send data before you set the cookie, you get errors

How to Make Cookies

  • You use the setcookie() function to make one cookie at a time
  • Cookie recipe (syntax):

    bool setcookie (string name [, string value [, int expire [, string path [, string domain [, int secure]]]]])

  • The parameters of the function are described in the PHP documentation: setcookie()
  • Most parameters are optional, though you usually set the first two or three
  • For example:
    setcookie("color", "blue", time() + 14400);

Lifetime of a Cookie

  • Like freshly-baked cookies, browser cookies have a fixed lifetime
  • The default is to delete the cookie when the user closes their browser
  • Thus, if you do not set an expiration you may lose your cookies
  • Since the expiration date is a Unix timestamp, setting their lifetime is easy
  • Use the time() function to get the current time and add on some number of seconds
    define('DAYS_30', 2592000);
    time() + DAYS_30;
    

Example of Setting a Cookie

  • We can set cookies on the user's browser with the following code:

    <?php
    define
    ("DAYS_1"86400);
    $cookieName "testCookie";
    $cookieValue "Chocolate chip!";
    $cookieExpires = (time() + DAYS_1);

    setcookie($cookieName$cookieValue$cookieExpires);
    ?>
    <html>
    <head><title>Cookie Set</title></head>
    <body>
    <h1>Yummmmmmm...cookie!</h1>
    </body>
    </html>

    Try it and view the source.

  • Note that you cannot see the cookie in the web page source
  • We will read the cookie in the next section

11.1.6: Requesting Cookies

  • Most people forget that you do not get cookies back until the user makes another HTTP request
  • Sometimes people spend hours debugging this when nothing is wrong!
  • For example, if you set a cookie named color with a value of blue on page 1
  • You do not get the cookie back until the user requests page 2 (or any other page)

Sending Cookie Messages

  • When a browser requests a URL, it first searches its stored cookies
  • If any are relevant to the URL, it sends them to the server
  • When PHP creates a page, it stores all the cookie data it receives in an array named $_COOKIE
  • To get a cookie, ask for it by name in the $_COOKIE array:
    echo $_COOKIE["testCookie"];
  • You can retrieve cookie data from the $_REQUEST array as well

For Example

  • Use the following script to get our test cookie back:

    <html>
    <head><title>Cookie Get</title></head>
    <body>
    <h1>Cookie type:
        <?php echo $_COOKIE["testCookie"]; ?></h1>
    </body>
    </html>

    Try it and view the source.

Checking the Cookie Jar

  • Sometimes you want to see all the cookies
    • Useful for debugging
  • One easy way is to use the dump() function you wrote in Activity 9.1

    <?php
    function dump($var) {
        echo 
    "\n<pre>";
        
    var_dump($var);
        echo 
    "</pre>";
    }
    ?>
    <html>
    <head><title>Cookie Monster</title></head>
    <body>
    <h1>Cookies:</h1>
    <?php dump($_COOKIE); ?>
    </body>
    </html>

    Try it and view the source.

11.1.7: More Cookie Tips and Tricks

The Cookie Monster

  • Sometimes you want to delete an existing cookie
  • You can delete a cookie using the setcookie() function
    • Just set the expiration to sometime in the past
  • For example:
    define("DAYS_1", 86400);
    setcookie("color", "blue", time() - DAYS_1);
    
  • To remove all cookies, you do something like:

    <?php
    ob_start
    ();
    define("DAYS_1"86400);
    foreach (
    $_COOKIE as $name=>$value) {
        echo 
    "Removing $name=$value<br>\n";
        
    setcookie($name""time() - DAYS_1);
    }
    ?>

Cookie Making Tip

  • When making cookies in a program, set your browser to warn you before saving a cookie
  • This creates a pop-up warning box that lets you know a cookie is set

Cookie Limitations

  • Cookies have limits imposed by specification
  • A browser can only keep the last 20 cookies sent from a particular domain
  • The maximum size of a cookie is 4KB
  • In addition, the more cookies you store, the larger the users HTTP request

Final Notes on Cookies

  • Some users do not like cookies and disable them
  • Some firewalls prevent exchange of cookies with web pages
  • You cannot read or write cookies on these computers
  • Make certain that your application does not require cookies to operate
  • Cookies are best used as a convenience feature (such as saving favorites)

More Information

Exercise 11.1

In this exercise we explore the use of query strings, hidden fields and cookies to store data between page requests.

Specifications

  1. Open the XAMPP Control Panel by double-clicking the icon on the desktop or by using the Apache Friends entry in the start menu.

    XAMPP icon

  2. Start the Apache and MySQL modules, if they are not already running.

    XAMPP control panel

  3. Verify the following files are installed in a subdirectory named includes of the htdocs/phptest directory:

    If needed, copy the files and paste them into a text editor such as TextPad. After saving, verify you saved the page without turning angle brackets and other special characters into HTML entities such as &lt; and &gt;. Also if needed, change the dbconvars.php values assigned to $dbuser and $dbpwd to match your MySQL installation. For more information see lesson 6.3.1: Connecting to a MySQL Database.

  4. In addition, verify the echo.php page is installed in the htdocs/phptest directory:
  5. Copy the following page into a text editor, save the file in your phptest directory as requestdata.php, and then view the file as a Web page in your browser using the address: http://localhost/phptest/requestdata.php
    <?php
    ob_start();
    
    main("Request Data");
    
    function main($title = "") {
        makeCookie();
        include "includes/header.php";
        showContent($title);
        include "includes/footer.php";
    }
    
    function makeCookie() {
        // Set cookie here
    }
    
    function showContent($title) {
    ?>
    <h1><?php echo $title ?></h1>
    <!-- Add query string in the action attribute -->
    <form action="echo.php" method="POST">
    <!-- Add hidden field here -->
    <input name="submitTest" type="submit" value="Send">
    </form>
    <?php
    }
    ?>
    

    You should see a page like the following in the browser:

    Press the Send button and notice that the query string appears in the echo page. For more information see section 11.1.2: Using Query Strings.

  6. Add a query string to the form by changing the action attribute to something like:
    <form action="echo.php?name=value" method="POST">
    

    Reload (refresh) your form page and press the Send button and notice that the query string appears in the echo page. For more information see section 11.1.2: Using Query Strings.

  7. Within the form tags, add a hidden field using code like:
    <input type="hidden" name="pid" value="12345">
    

    Reload (refresh) your form page and press the Send button and notice that the name and value of the hidden field appears in the echo page. For more information see section 11.1.3: Using Hidden Fields.

  8. In the makeCookie() function, add code like the following to set a cookie:
    define("DAYS_1", 86400);
    $name = "testCookie";
    $value = "Chocolate chip!";
    $expires = (time() + DAYS_1);
    setcookie($name, $value, $expires);
    

    Reload (refresh) your form page and press the Send button and notice that the name and value of the cookie appears in the echo page. For more information see section 11.1.5: Making Cookies.

  9. Submit your final requestdata.php file to Blackboard as part of assignment 11.

As time permits, be prepared to answer the Check Yourself questions in the section: 11.1.8: Summary.

11.1.8: Summary

  • Sometimes you need to save application data across multiple Web pages
    • One example is a catalog and shopping cart
    • Another is a multiple-page survey form
  • One technique is to use query strings and save data with the URL:
    <a href="cart.php?pid=12345">Add To Cart</a>
    
  • Another way is HTML hidden fields that contain values without displaying them:
    <input type="hidden" name="pid" value="12345">
  • Values set in hidden fields are processed the same as any other form data by PHP:
    $pid = $_REQUEST["pid"];
  • Cookies allow a Web server to save small pieces of data on the user's computer
  • To make a cookie, you use the setcookie() function
    setcookie("color", "blue", time() + 14400);
  • Remember that cookies are limited in both number and size
  • Thus, cookies should be limited to simple applications that do not require large amounts of data
  • In addition, cookies can be refused or deleted by the user
  • Because of this, you need to make certain that your application does not require cookies to operate
  • Cookies are usually best for non-essential features like user preferences or lists of favorite items

Check Yourself

  1. True or false? HTTP is a stateless protocol. (11.1.1)
  2. How do you add a query string to a URL? (11.1.2)
  3. True or false? Hidden fields are hidden but not completely invisible to the user. (11.1.3)
  4. How can you view the contents of a hidden field? (11.1.3)
  5. True or false? Cookies work by storing data on the browser's computer. (11.1.4)
  6. True or false? Cookies are a security risk. (11.1.4)
  7. True or false? Cookies are a privacy risk. (11.1.4)
  8. Given the following information, what code would you write to make a cookie? (11.1.5):
    • cookie name is "color"
    • cookie value is "blue"
    • cookie expires in 30 days
  9. True or false? Cookies can be retrieved using the $_COOKIE superglobal array. (11.1.6)
  10. True or false? Cookies can be retrieved using the $_REQUEST superglobal array. (11.1.6)
  11. True or false? You delete cookies using the setcookie() function. (11.1.4)

11.2: Storing Data on the Server

Learner Outcomes

At the end of the lesson the student will be able to:

  • Start a session
  • Add a variable to the $_SESSION superglobal

11.2.1: Overview of PHP Sessions

  • A session is a way to save data for a user on the server
  • When a session is started, the user is assigned a unique session identifier:
    • Usually stored in a cookie named PHPSESSID
    • Can also be part of the URL
  • On the server side, a matching temporary file is started using the same identifier in the name
  • Any request to the server includes this session identifier
  • The session identifier is used to locate any data assigned to the user

Example of a Session

  1. The user requests a page that starts a session, such as welcome.php
  2. PHP generates a session ID and creates a file for storing the session-related variables
  3. PHP sets a cookie to hold the session ID in the page sent back to the user
  4. The browser records the cookie and includes it in subsequent requests.
  5. In the example below, the user then requests next.php:
    • The browser includes the PHPSESSID cookie in the request
  6. PHP automatically looks up the session information in the session store
  7. PHP generates the page, allowing the programmer to personalize the page using session data
  8. The browser displays the personalized page to the user

    From www.oreilly.com

    Source: http://www.oreilly.com/catalog/webdbapps/chapter/ch08.html

11.2.2: Starting Sessions

  • To initialize a session, you call the session_start() function:
    session_start();
  • If the request contains a PHPSESSID cookie, the call to session_start() causes PHP to locate the session file
  • Otherwise, PHP generates a session identifier and creates a new session file
  • PHP automatically includes the PHPSESSID cookie in the response to the page request

For Example

<?php
session_start
();
?>
<html>
<head><title>Start a Session</title></head>
<body>
<h1>Started a session...</h1>
<pre>
<?php
echo "Cookie name: ".session_name()."\n";
echo 
"Cookie value (SID):  ".session_id()."\n";
echo 
"Session file path: ".session_save_path()."\n";
?>
</pre>
</body>
</html>

  • Now you can view the session information that was created
  • Note that reloading the page does not change the session identifier (SID)
  • Does anyone have the same SID (cookie value)?

Common Pitfall

  • Sometimes people inadvertently start two or more sessions
  • They do this by putting session_start() in multiple include files
  • The outcome is often confusing and may produce error notices
  • To prevent this problem, you should conditionally start your sessions:
    if (!session_id()) session_start();
    
  • Another option is to use:
    if (session_id() == "") session_start();
    
  • They work the same because of how PHP determines true and false values

11.2.3: Using Session Variables

  • You must call session_start() before using any session variables
  • The best method of working with session variables is the superglobal array $_SESSION
  • To add a variable to a session:
    $_SESSION["color"] = "blue";
  • To retrieve the value of a session variable:
    $color = $_SESSION["color"];
  • To remove a variable from a session:
    unset($_SESSION["color"]);

Example Using a Session

  • This script changes the value of a session value on each page load

    <?php
    if (!session_id()) session_start();

    if (!isset(
    $_SESSION["count"])) {
        
    $_SESSION["count"] = 0;
    }
    $_SESSION["count"]++;
    $count $_SESSION["count"];
    ?>
    <html>
    <head><title>Session Variables</title></head>
    <body>
    <h1>Welcome!</h1>
    <p>You have been here <?php echo $count ?> times</p>
    </body>
    </html>

Objects as Session Variables

  • You must load class definitions before calling session_start()
  • This is because the PHP needs to know the class structure to recreate the session

Viewing All Session Data

  • Sometimes you want to see all the session data
  • For this we can use the var_dump() like:

    <?php
    if (!session_id()) session_start();
    ?>
    <html>
    <head><title>Session Data</title></head>
    <body>
    <h1>Sessions:</h1>
    <pre>
    <?
    var_dump
    ($_SESSION);
    ?>
    </pre>
    </body>
    </html>

11.2.4: Ending Sessions

  • You may need to destroy sessions during an application
    • One example is when a user logs out
  • Calling the session_destroy() function removes the session file from the server
  • However, it does not remove the session data or the PHPSESSID cookie from the browser
  • To entirely remove the session, you need to reset the $_SESSION array and remove the session cookie
  • Also note that you must call session_start() before calling session_destroy()
  • You can see the steps to completely destroy a session in the following example

Example Showing How to Destroy a Session

<?php
// Initialize the session before destroying it
if (!session_id()) session_start();
// Clear all of the session variables
$_SESSION = array();
// Remove the session cookie
if (isset($_COOKIE[session_name()])) {
    
setcookie(session_name(), ''time() - 86400'/');
}
// Finally, destroy the session
session_destroy();
?>
<html>
<head><title>Session Destroy</title></head>
<body>
<h1>Goodbye!</h1>
<pre>
<?php
echo "Cookie name: ".session_name()."\n";
echo 
"Cookie value (SID):  ".session_id()."\n";
echo 
"Session file path: ".session_save_path()."\n";
?>
</pre>
</body>
</html>

Exercise 11.2

In this exercise we explore how to use session variables.

Specifications

  1. Verify your web server is started and all the support files are installed as specified in the first 3 steps of exercise 11.1.

  2. In addition, copy the following code into a text editor and save it as sessionecho.php in the htdocs/phptest directory:
    <?php
    if (!session_id()) session_start();
    ?>
    <html>
    <head><title>Session Data</title></head>
    <body>
    <h1>Sessions:</h1>
    <pre>
    <?
    var_dump($_SESSION);
    ?>
    </pre>
    </body>
    </html>
    
  3. Copy the following page into a text editor, save the file in your phptest directory as sessiondata.php, and then view the file as a Web page in your browser using the address: http://localhost/phptest/sessiondata.php
    <?php
    ob_start();
    if (!session_id()) session_start();
    
    main("Session Data");
    
    function main($title = "") {
        include("includes/header.php");
        showContent($title);
        include("includes/footer.php");
    }
    
    function showContent($title) {
        // Put session variable(s) here
    ?>
    <h1><?php echo $title ?></h1>
    <form action="sessionecho.php" method="POST">
    <input name="submitTest" type="submit" value="Send">
    </form>
    <?php
    }
    ?>
    

    You should see a page like the following in the browser:

    Press the Send button and notice there is no session data as of yet.

  4. To the sessiondata.php page, add several session variables like:
    $user = "eparrish";
    $_SESSION["user"] = $user;
    
  5. After adding the session variables, reload (refresh) your sessiondata.php page and press the Send button. Verify you see session variables like:
    array(1) {
      ["user"]=>
      string(8) "eparrish"
    }
    
  6. Submit your final sessiondata.php file to Blackboard as part of assignment 11.

As time permits, be prepared to answer the Check Yourself questions in the section: 11.2.5: Summary.

11.2.5: Summary

  • Sessions are a way to manage the state (session variables) for a user
  • When a session is started, the user is assigned a session identifier
    • Usually stored in a cookie named PHPSESSID
    • Can also be part of a URL
  • On the server side, a matching temporary file is started using the same identifier in the name
  • Any request to the server includes this session identifier
  • The session identifier is used to locate any data assigned to the user
  • To start a session, call the session_start() function:
    if (!session_id()) session_start();
  • As shown above, you should start the session conditionally
  • You must start a session before you can use any session variables
  • The best method of working with session variables is the superglobal array $_SESSION
  • To add a variable to a session:
    $_SESSION["color"] = "blue";
  • To retrieve the value of a session variable:
    $colorPref = $_SESSION["color"];
  • To remove a variable from a session:
    unset($_SESSION["color"]);
  • You can end a started session using the session_destroy() function:
    session_destroy();

Further Information

Check Yourself

As time permits, be prepared to answer these questions. You can find more information by following the links after the question.

  1. What is a session? (11.2.1)
  2. What is the advantage of using session variables over using hidden fields or query strings? (11.2.1)
  3. What is the advantage of using session variables over using using cookies? (11.2.1)
  4. What two ways can session identifiers be tracked by PHP? (11.2.1)
  5. What function call starts a session? (11.2.2)
  6. What code can you use to make certain you do not start multiple sessions? (11.2.2)
  7. What code can you use to create a session variable named "color" and assign it the value "blue"? (11.2.3)
  8. What are the three steps needed to completely destroy a session? (11.2.4)

11.3: User Authentication with Session Control

Learner Outcomes

At the end of the lesson the student will be able to:

  • Describe the functions needed for user registration and login
  • Implement a self-registration system in your project
  • Implement a login system with session control in your project

11.3.1: Authentication Principles

  • Authentication means asking people to prove their identity
  • You often want to control user access to parts of your Web site
  • Sometimes you deal with sensitive information such as bank accounts
  • Other times you want to provide information to paying customers only
  • The most common method of authentication is by collecting a user name and password
  • Passwords are relatively simple to implement and use
  • The main idea is that only you and the system know your password
  • When you provide your login and password, the system believes it is you
  • Passwords by themselves do not provide strong authentication
    • Most passwords are easily guessed
    • Most people only have a few passwords they use over and over
    • Passwords can be captured electronically: keystroke capture, packet sniffer
  • Even with their flaws, passwords are acceptable for some uses
  • We will look at a system of password protection that allows users to self-register
    • If you do not want this option, just remove it
  • Also, you can extend this system to include saving user preferences

11.3.2: Design Overview

  • The system design is based on collecting a username and password
  • Any page that needs securing is redirected to a login page, unless the user has already logged in
  • The username and password is checked against a list of valid users stored in a database
  • If validated, the login script redirects the user back to the requested page

Desired Solution

  1. Users can register by entering a username, password and email
  2. Users are required to login to access secure areas
  3. Users can logout to destroy cookies and session information
  4. The Web site remembers if a user is authenticated
    • So there is no need to login to every secure page
  5. It is easy to add security to specific pages
  6. Passwords are encrypted when they are stored in the database

Sequence of Operations

  1. A user goes to a secured page like members.php
  2. At the secured page, we include code that checks if the user has logged in or not
  3. If the user is logged in, they can view the page
  4. Otherwise:
    1. The secured page name is stored in a session variable named refPage
    2. The user is redirected to the login.php page
  5. At the login.php page, the user can either login or register
  6. If the login is valid, the user is automatically redirected back to the secured page
  7. If the user chooses to register, they click the link for the register.php page
  8. After they register, the user is redirected back to the secured page

secure page

Sample Operation

  • To see the system in action, click here for the Members page
  • Note that you are automatically redirected to login.php unless you are already logged in

Database Design

  • We will use the Artzy database for our design
  • Login uses the following columns of the database table named users
UserName Salt Userpwd Email
 inewton  KDME  2bc99e382a35c359  inewton@aol.com
 jbond  AEFG  27272e1c23ca3491  jbond@mi7.uk
 jjones  WDPF  278b41cd00f230ab  jjones@aol.com

Solution Files

Included Files

11.3.3: Implementing Registration

  • The page that implements registration is named register.php
  • We use the same structure for forms as we discussed before:
    • main(): controls the operation of the page
    • checkForm(): checks the input form for errors
    • processData(): process the data
    • showContent(): displays the content of the page
  • We save database and session data on this page
  • Also we use included files for common code:
  • Note the use of constants to avoid using "magic numbers"
  • Also note the session_start() function
  • In addition, we use the crypt() function to encrypt the password

<?php
/**
* register.php
* Registers a user for later authentication
*
* @author Ed Parrish
* @version 1.3 5/02/08
*/
ob_start();
require_once 
"includes/formlib.php";
require_once 
"includes/redirect.php";
if (!
session_id()) session_start();
define("MIN_USER"6);
define("MIN_PWD"6);
define("DEFAULT_PAGE""echo.php");

main("Artzy Registration");

// Form processing logic
function main($title "") {
    
$f = new FormLib();
    if (isset(
$_POST["submitTest"])) {
        require_once(
"includes/dbconvars.php");
        @
$db mysql_connect($dbhost$dbuser$dbpwd)
                or die(
"Could not connect");
        @
mysql_select_db($dbname$db)
                or die(
"Could not select database");
        
checkForm($f$db);
        if (!
$f->isError()) { // data is OK
            
processData($f$db);
            
$refPage DEFAULT_PAGE;
            if (isset(
$_SESSION["refPage"])) {
                
$refPage $_SESSION["refPage"];
                
// Session var no longer needed
                
unset($_SESSION["refPage"]);
            }
            
redirect($refPage);
        }
        
mysql_close($db);
    }
    include(
"includes/header.php");
    
showContent($title$f);
    include(
"includes/footer.php");
}

// Check form for errors and return error messages
function checkForm(&$f$db) {
    
$f->isInvalidEmail('email',
            
'Please enter a valid email');
    
$f->isEmpty('username',
            
'Please enter a username');
    
$f->isEmpty('password',
            
'Please enter a password');
    
$f->isEmpty('password2',
            
'Please enter a confirming password');
    if (
$f->isError()) return;

    
$user $f->getValue('username');
    if (
strlen($user) < MIN_USER) {
        
$f->addError('username'$user,
            
"User name must be at least ".MIN_USER
            
." characters.");
    }
    
$pwd $f->getValue('password');
    if (
strlen($pwd) < MIN_PWD) {
        
$f->addError('password'$pwd,
            
"Password must be at least ".MIN_PWD
            
." characters.");
    }
    if (
$pwd != $f->getValue('password2')) {
        
$f->addError('password2''',
            
"Passwords do not match");
    }
    if (
$f->isError()) return;

    
// Check database
    
$user $f->getValue('username');
    
$sql "SELECT Username, Userpwd FROM users
            WHERE username='$user'"
;
    @
$result mysql_query($sql)
            or die(
"Query failed");
    
$numRows mysql_num_rows($result);
    if (
$numRows !== 0) {
        
$msg "Username taken - "
               
."please choose another";
        
$f->addError($user''$msg);
    }
    
mysql_free_result($result);
}

// Process the data
function processData($f$db) {
    
// Save database data
    
$user $f->getValue('username');
    
$salt substr($user02);
    
$pwd crypt($f->getValue('password'), $salt);
    
$email $f->getValue('email');
    
$sql "INSERT INTO users
            (Username, Salt, Userpwd, Email)
            VALUES ('$user','$salt','$pwd','$email')"
;
    @
mysql_query($sql) or die("Query failed in save");

    
// Save session data
    
$_SESSION['user'] = $user;
}

// Display the content of the page
function showContent($title$f) {
    echo 
"<h1>$title</h1>";
    echo 
$f->reportErrors();
    echo 
$f->start();
?>
<p><table cellpadding="6">
<tr>
  <td><?php echo $f->formatOnError('email',
    
'Email address'?></td>
  <td><?php echo $f->makeTextInput('email'40?></td>
</tr>
<tr>
  <td><?php echo $f->formatOnError('username',
    
'Username'?></td>
  <td><?php echo $f->makeTextInput('username'?></td>
</tr>
<tr>
  <td><?php echo $f->formatOnError('password',
    
'Password'?></td>
  <td><?php echo $f->makePassword('password'?></td>
</tr>
<tr>
  <td><?php echo $f->formatOnError('password2',
    
'Confirm password'?></td>
  <td><?php echo $f->makePassword('password2'?></td>
</tr>
<tr>
  <td><?php echo $f->makeButton("Save"?></td>
  <td>&nbsp;</td>
</tr>
</table></p>
<?php
    
echo $f->finish();
}
?>

11.3.4: Implementing Login

  • The page that implements login is named login.php
  • We use the same structure for forms as we discussed before
    • main(): controls the operation of the page
    • checkForm(): checks the input form for errors
    • processData(): process the data
    • showContent(): displays the content of the page
  • We save cookie and session data on this page
  • Also we use included files for common code:
  • Note use of heredoc strings
  • Also note that passwords are not returned on error
    • Unnecessary transmission of sensitive information

<?php
/**
* login.php
* Login page to authenticate users
*
* @author Ed Parrish
* @version 1.3 5/02/08
*/
ob_start();
require_once 
"includes/formverifier.php";
require_once 
"includes/redirect.php";
if (!
session_id()) session_start();
define('DAYS_30'2592000);
define("DEFAULT_PAGE""echo.php");

main("Artzy Login Page");

// Form processing logic
function main($title "") {
    
$f = new FormVerifier();
    if (isset(
$_POST["submitTest"])) {
        
checkForm($f);
        if (!
$f->isError()) { // data is OK
            
processData($f);
            
$refPage DEFAULT_PAGE;
            if (isset(
$_SESSION["refPage"])) {
                
$refPage $_SESSION["refPage"];
            }
            
redirect($refPage); // return to sender
        
}
    }
    include(
"includes/header.php");
    
showContent($title$f);
    include(
"includes/footer.php");
}

// Check the input form for errors
function checkForm(&$f) {
    
$f->isEmpty('username',
            
'Please enter a username');
    
$f->isEmpty('password',
            
'Please enter a password');
    if (
$f->isError()) return;

    
$user $f->getValue('username');
    
$salt substr($user02);
    
$pwd crypt($f->getValue('password'), $salt);

    require_once(
"includes/dbconvars.php");
    @
$db mysql_connect($dbhost$dbuser$dbpwd)
            or die(
"Could not connect");
    @
mysql_select_db($dbname$db)
            or die(
"Could not select database");
    
$sql "SELECT Username, Userpwd FROM users
            WHERE Username='$user'
            AND Userpwd='$pwd'"
;
    
$result mysql_query($sql);
    
$row mysql_fetch_row($result);
    if (!
$row || mysql_num_rows($result) !== 1) {
        
$f->addError('''',
            
"Invalid username or password");
    }
    
mysql_free_result($result);
    
mysql_close($db);
}

// Process the data
function processData($f) {
    
// Save data in session variables
    
$user $f->getValue('username');
    
$_SESSION['user'] = $user;
    
// Save data in cookies
    
if ($f->getValue('save') === 'y') {
        
setcookie("user"$usertime() + DAYS_30);
    }
}

// Display the content of the page
function showContent($title$f) {
    echo 
'<div align="center">';
    echo 
"<h1>$title</h1>";
    echo 
$f->reportErrors();
    
$user $f->getValue('username');
    
$pwd $f->getValue('password');
    
$uname $f->formatOnError('username''User name');
    
$pword $f->formatOnError('password''Password');
    echo <<<HTML
<p>New users <a href="register.php">click here</a></p>
<form name="login" action="login.php" method="post">
<table cellpadding="3">
<tr>
<td>$uname</td>
<td>
  <p><input type="text" name="username" value="$user"></p>
</td>
</tr>
<tr>
<td>$pword</td>
<td>
  <p><input type="password" name="password"></p>
</td>
</tr>
<tr>
<td colspan=2>
  <input type="checkbox" name="save" value="y" checked>
  Remember my ID on this computer</font>
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><input type="submit" name="submitTest"
  value="Login"></td>
</tr>
</table>
</form>
</div>
HTML;
}
?>

11.3.5: Implementing Logout

  • Logout provides added security for users who share computers
  • Many sites delete usernames from cookies when people select logout
  • The page that implements logout is named logout.php
  • Because this is a simpler page, we use a simpler page structure:
    • main(): controls the operation of the page
    • showContent(): displays the content of the page
  • We destroy cookie and session data on this page
  • Also we use included files for common code:

<?php
/**
* logout.php
* Logout page removes session and cookie data
*
* @author Ed Parrish
* @version 1.3 5/02/08
*/

ob_start();
if (!
session_id()) session_start();

main("Artzy Secure Logout");

// Control the operation of the page
function main($title "") {
    
$redirect "echo.php";
    
$other "<meta http-equiv=\"Refresh\"";
    
$other .= "content=\"5;URL=$redirect\">\n";
    
$user "";
    if (isset(
$_SESSION['user'])) {
        
$user $_SESSION['user'];
    }
    
$_SESSION = array();
    if (isset(
$_COOKIE[session_name()])) {
        
setcookie(session_name(), ''time() - 86400'/');
    }
    
session_destroy();
    include(
"includes/header.php");
    
showContent($title$redirect$user);
    include(
"includes/footer.php");
}

// Display the content of the page
function showContent($title$redirect$user) {
    
$msg $user;
    if (!
$user) {
        
$msg "You are";
    }
    echo 
"<h1>$title</h1>";
    echo<<<HTML
<p>$msg logged out securely.</p></p>
<p>Click <a href="$redirect">here</a> to continue.</p>
HTML;
}
?>

Try it!.

11.3.6: Securing Pages

  • We can select which pages to secure by using an include file:
    require_once "secure.php";
  • Checks whether user is authenticated and redirects to the login page if not
  • Must include before any HTML written to allow redirection
  • Saves current page location as a session variable for when login completes
  • Login automatically returns the user to originating page (e.g. Members)

<?php
/**
* secure.php
* Include file for securing pages
*
* @author Ed Parrish
* @version 1.3 5/02/08
*/
require_once "redirect.php";
if (!
session_id()) session_start();

requireLogin();

// Returns True if user is authenticated, otherwise False
function requireLogin() {
    if (!
isAuthenticated()) {
        
$_SESSION['refPage'] = $_SERVER['PHP_SELF'];
        
redirect("login.php");
    } else {
        if (isset(
$_SESSION["refPage"])) {
            unset(
$_SESSION["refPage"]);
        }
        echo 
"<!-- Validated at ".date('Y-m-d H:i:s')." -->";
    }
}

// Returns 1 if current user is authenticated, otherwise 0
function isAuthenticated() {
    if (!isset(
$_SESSION['user'])) {
        return 
0;
    } else {
        return 
1;
    }
}
?>

Secure Page Example

  • To demonstrate the secure page feature, we include a "members only" page

<?php
/**
* members.php
* Members only secure page for Artzy store
*
* @author Ed Parrish
* @version 1.3 5/02/08
*/
ob_start();
require_once 
"includes/secure.php";
if (!
session_id()) session_start();

main("Members Only!");

// Control the operation of the page
function main($title "") {
    include(
"includes/header.php");
    
showContent($title);
    include(
"includes/footer.php");
}

// Display the content of the page
function showContent($title) {
    
$user "";
    if (isset(
$_SESSION["user"])) {
        
$user " ".$_SESSION["user"];
    }
    echo<<<HTML
<h1>$title</h1>
<p>Hello $user,</p>
<p>You are on a protected page.</p>
<p><a href="logout.php">Logout here</a></p>
HTML;
}
?>

Try it!.

Exercise 11.3

In this exercise we try out the rigistration and login system on our local computers.

Specifications

  1. Verify your Web server and database is started and all the support files are installed as specified in the first 4 steps of exercise 11.1.

  2. Add the following files to the includes subdirectory of phptest:

    Copy the file and paste it into a text editor such as TextPad. After saving, verify the page saved without turning angle brackets and other special characters into HTML entities such as &lt; and &gt;.

  3. Add the following files to the phptest directory:

    Copy the file and paste it into a text editor such as TextPad. After saving, verify the page saved without turning angle brackets and other special characters into HTML entities such as &lt; and &gt;.

  4. Run the application by accessing the members.php page on your system.

    Register and login to try out the system.

  5. There is no need to turn in any files from this exercise.

As time permits, be prepared to answer the Check Yourself questions in the section: 11.3.7: Summary.

11.3.7: Summary

  • You often want to control user access to parts of your Web site
  • The most common method of control is to collect a username and password
  • When the user provides a valid username and password, the system accepts their identity
  • The design presented today keeps usernames and passwords in a database:
    • Makes use of the artzy database Users table
    • Passwords are encrypted before storing them in the database
  • Users are allowed to self-register with a username, password and email
  • Users can choose to increase their security by logging out
    • Destroys cookies and session information
  • You can control user access to any of your project pages by simply including a file:
    require_once "includes/secure.php";
    
  • You could extend the system to detect returning users using cookie data and greet them "personally"
  • Also, you could extend this system to include storing user preferences

Check Yourself

As time permits, be prepared to answer these questions. You can find more information by following the links after the question.

  1. True or false? Login plus password authentication is considered strong. (11.3.1)
  2. Why is the purpose of salt? (11.3.2)
  3. What function is used to encrypt passwords? (11.3.3)
  4. Why does one-way encryption work for passwords? (11.3.3)
  5. Why is logout a good idea? (11.3.5)
  6. What file do you include to secure a page? (11.3.6)

Wrap Up

Due Next:
A11-Authenticating Users (5/11/09)
Quiz 11 and Discussion Chapter 12 (5/11/09)
When class is over, please shut down your computer if it is on
Home | WebCT | Announcements | Course info | Expectations | Schedule
Project | Help | FAQ's | HowTo's | Links
Last Updated: June 03 2009 @22:24:06