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

Objectives

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

  • 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:

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 URL Rewriting

  • URL rewriting means that you encode the URL to include more information
  • The information appears as part of the URL
  • You can use URL rewriting 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 URL rewriting:
  • url?paramName1=paramValue1¶mName2=paramValue2&...
    

URL Rewriting 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 URL Rewriting

  • Most browsers limit the number of characters that can be passed by a URL to 2,000 characters.
  • Since URL rewriting only works with the HTTP GET method, all variables are visible in the browser's URL field.
  • If a user creates a bookmark for a page that uses URL rewriting, 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 URL rewriting 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 steal a password
    • Cannot format a hard disk
    • Cannot send e-mail
    • 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
  • Another person can use the public computer and look at the cookie files
  • 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

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 Exercise 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

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 URL rewriting 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

Exercise 11.1

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

Specifications

  1. Save the code that follows as requestdata.php and requestecho.php.
  2. Modify the requestdata.php page to add a CGI (request) variable to the action attribute of the form.
  3. Press the button and verify you see the CGI variable in both the URL and reported in the body of the requestecho.php page.
  4. Add a hidden variable to the form.
  5. Follow the "Return to Form" link and test your hidden variable by pressing the button again.
  6. You should see your hidden variable displayed in the body of the requestecho.php page.
  7. Write code to set a cookie in the makeCookie() function of the requestdata.php page.
  8. Follow the "Return to Form" link and test your cookie by pressing the button again.
  9. Turn in both files as your solution to this exercise.

File: requestdata.php

<?php
ob_start
(); // allow header modification

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) {
    echo<<<HTML
<h1>$title</h1>
<!-- Add CGI variable in action field -->
<form action="requestecho.php" method="POST">
<!-- Add hidden field here -->
<input name="submit" type="submit" value="Send Data">
</form>

HTML;
}
?>

File: requestecho.php

<?php
main
("Request Data Echoed");

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

function 
showContent($title) {
    echo 
"<h1>$title</h1>\n";
    foreach (
$_REQUEST as $name=>$value) {
        echo 
"$name=$value<br>\n";
    }
    echo 
'<p><a href="requestdata.php">Return to form</a>';
}
?>

11.2: Storing Data on the Server

Objectives

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

What is a Session?

  • 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
  9. From www.oreilly.com

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

11.2.2: Starting Sessions

  • To start 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();
    

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>

  • Why is the if (!isset()) statement needed?

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
  • Again, you can use the dump() function you wrote in Exercise 9.1
  • <?php
    if (!session_id()) session_start();

    function 
    dump($var) {
        echo 
    "\n<pre>";
        
    var_dump($var);
        echo 
    "</pre>";
    }
    ?>
    <html>
    <head><title>Session Data</title></head>
    <body>
    <h1>Sessions:</h1>
    <?php dump($_SESSION); ?>
    </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>

  • You can verify the session data is gone by using the view all session data function

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

Exercise 11.2

In this exercise we explore how to use session variables.

Specifications

  1. Save the code that follows as sessiondata.php and sessionecho.php.
  2. Modify the sessiondata.php page to set one or more session variables.
  3. Press the button and verify you see the session variable(s) in the body of the sessionecho.php page.
  4. Turn in both files as your solution to this exercise.

File: 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

    
echo<<<HTML
<h1>$title</h1>
<form action="sessionecho.php" method="POST">
<input name="submit" type="submit" value="Send Data">
</form>
HTML;
}
?>

File: sessionecho.php

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

main("Session Data Echoed");

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

function 
showContent($title) {
    echo 
"<h1>$title</h1>\n";
    foreach (
$_SESSION as $name=>$value) {
        echo 
"$name=$value<br>\n";
    }
    echo 
'<p><a href="sessiondata.php">Return to form</a>';
}
?>

11.3: User Authentication with Session Control

Objectives

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 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 that allows users to self-register
    • If you do not want this option, just remove it
  • Also, you can extend this system to include user preferences

11.3.2: Design Overview

  • The overall 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 with a username, password and email
  2. Users are required to login to secure areas
  3. Users can logout to destroy cookies and session information
  4. The Web site can remember if a user is authenticated
    • So there is no need to login to every secure page
  5. Must be 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 the page members.php, which is a secured page
  2. At the members.php page, a check is made if the user has logged in or not
  3. If the user is logged in, they can view the page
  4. Otherwise:
    1. The members.php page iname s 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 members.php 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 members.php 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
    • saveData(): save 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.2 11/12/05
*/
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""index.html");

main("Artzy Registration");

// Control the operation of a page
function main($title "") {
    
$f = new FormLib();
    if (isset(
$_POST["submit"])) {
        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
            
saveData($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->isEmailAddress('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);
}

// Save the data
function saveData($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 a 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',
    
'Preferred username<br>(at least '.MIN_USER
    
.' characters)'?></td>
  <td><?php echo $f->makeTextInput('username'?></td>
</tr>
<tr>
  <td><?php echo $f->formatOnError('password',
    
'Password<br>(At least '.MIN_PWD
    
.' characters)'?></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
    • saveData(): save 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 as an alternative to FormLib functions
    • So you can see examples of both ways
  • 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.1 11/12/05
*/
ob_start();
require_once(
"includes/formverifier.php");
require_once(
"includes/redirect.php");
if (!
session_id()) session_start();
define('DAYS_30'2592000);
define("DEFAULT_PAGE""index.html");

main("Artzy Login Page");

// Control the operation of a page
function main($title "") {
    
$f = new FormVerifier();
    if (isset(
$_POST["submit"])) {
        
checkForm($f);
        if (!
$f->isError()) { // data is OK
            
saveData($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 form for errors and return error messages
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);
}

// Save the data
function saveData($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 a 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="submit" 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.2 11/12/05
*/

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

main("Artzy Secure Logout");

// Control the operation of a page
function main($title "") {
    
$redirect "http://".$_SERVER['HTTP_HOST']
                .
"index.html";
    
$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");
}

/**
* Purpose: Display the content of a 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;
}
?>

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.2 11/12/05
*/
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.1 11/12/05
*/
ob_start();
require_once(
"includes/secure.php");
if (!
session_id()) session_start();

main("Members Only!");

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

// Display the content of a 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;
}
?>

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

Exercise 11.3

Use the next 15 minutes to complete the following.

  1. Copy the following files into your public_html directory:
  2. Also copy the following include files into your public_html/includes directory:
  3. Run the application by accessing the members.php page on your system.

Wrap Up

Home | WebCT | Announcements | Course info | Expectations | Schedule
Project | Help | FAQ's | HowTo's | Links

Last Updated: April 26 2006 @17:40:01