Skip to content

Lecture Notes - Week 9

Readings

  • Chapters:
    • 20 - Basic HTTP Authentication
    • 21 - Persistence

Screencast - Week 9

Outline of Topics

  • Basic HTTP Authentication
  • Persistence Using:
    • Cookies
    • Session Variables
    • The Database

Lecture

Basic HTTP Authentication

So far, we've been creating applications that have no protection from someone deleting or modifying all our data. There are several ways we can add protection to our applications, many of which we will discuss going forward. In this section, we'll discuss one method called HTTP authentication, also known as basic authentication.

HTTP authentication is a simple mechanism we can use to protect access to our Student Listing application by authenticating users who want to add, edit, or remove students.

Here's how it will work. When we navigate to a page we want to protect with basic authorization, we want to see a dialog pop up asking for a user name and password:

This dialog continues to pop up as long as the user enters the incorrect credentials. Only after entering the correct credentials can the user proceed to the webpage that's been protected.

If the user presses the Cancel button, the following message will appear:

How does HTTP Authentication work?

  • The username and password are sent to the PHP script using the super global $_SERVER in $_SERVER['PHP_AUTH_USER'] and $_SERVER['PHP_AUTH_PW']:

  • HTTP Authentication is sent using headers. Everytime a webpage is requested headers are sent from the server to the client

  • Headers control how and what kind of information is passed between the client and server

  • Headers usually (but not always) consist of a name/value pair separated by a colon

  • Here’s a typical HTTP GET request from the client:

1
2
3
4
5
6
7
8
GET /index.php HTTP/1.1 <-- HTTP GET REQUEST
Host: www.studentdetails.net
Connection: close
User-Agent: Mozilla/24.0...
Accept-Charset: ISO-8859-1...
Cache-Control: no
Accept-Language: de,en;q=0.7...
...
  • Here's a typical HTTP response from the server:
1
2
3
4
5
6
HTTP/1.1 200 OK
Date: Tue, 31 Aug 2021 17:45:00 GMT
Server: Apache/2.4.41...
X-Powered-By: PHP/7.4
Transfer-Encoding: chunked
Content-Type: text/html
  • The header() function is used to create HTTP headers and send them from a script

  • Headers are sent to the browser to process before any HTML content is sent

  • When sending headers in PHP it has to be the first thing in your PHP code. No blank lines before the <?php tag:

1
2
3
<?php
    header('Content-Type: text/html');
?>

Authenticating requires sending a couple of headers

  • As long as the password and username are incorrect these two headers will be sent:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php
    $username = 'student';
    $password = 'student';

    // IF Password OR Username are empty
    // OR Password  OR Username don't match
    // send HTTP authentication headers
    if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])
        || $_SERVER['PHP_AUTH_USER'] !== $username
        || $_SERVER['PHP_AUTH_PW'] !== $password)
    {

        header('HTTP/1.1 401 Unauthorized');
        header('WWW-Authenticate: Basic realm="Student Listing"');
        $invalid_response = "<h2>Students</h2><h4>You must enter a "
                            . "valid username and password to access this page.</h4>";
        exit($invalid_response);
    }
  • If the user cancels out of sending the correct credentials, the exit() function will be called and no HTML content is sent

  • Once you have entered the credentials for a particular realm you will not be asked to reenter the credentials as long as you are in the same session

Let's go ahead and add Basic Authentication to our Student Listing application for the add, edit, and remove student features.

Persistence

Persistence. This is a big word that means "remembering". In the world of web development, it means storing information for longer than a single HTTP Request/Response transaction. Remember back in week 6 we mentioned that the web is stateless? Very often we need to persist information past a single HTTP transaction. One way we mentioned is to use hidden variables. This is clunky and vulnerable to security attacks. In this section we'll talk about three other mechanisms to persist data: cookies, session variables, and the database.

Cookies

Cookies allow the persistence of small pieces of string data on the client’s browser, have a time limit and can be deleted at will

The components of a cookie are:

  • Name: The unique name of the cookie
  • Value: The value stored in the cookie
  • Expiration Date: The date and time when the cookie expires

A cookie lasts as long as its set expiration date and time. If you don’t set a cookie’s expiration date and time, it lasts until the user dismisses the browser session. A cookie can only be read or modified by the site that sets it for security and privacy.

Is it true that a cookie can only be read or modified by the site that sets it for security and privacy? What about a user using Developer Tools to change the value of a cookie?

😱

Using Cookies with PHP

To create a cookie in PHP, use the function setcookie(). To specify the expiration date, we use the time() function to specify it as a UNIX timestamp:

1
2
3
4
// Expires when browser session ends
setcookie('user_id', '1');
// Expires 1 hour from now
setcookie('user_name', 'kenmarks', time() + 3600);

To use the cookie, you use the superglobal $_COOKIE[] to retrieve its value:

1
<p class="login">You are logged in as <?= $_COOKIE['user_name'] ?>.</p>;

To delete a cookie, use setcookie() to set a time in the past. Doing so tells the user’s browser to remove it:

1
2
// Set the time back one hour from now
setcookie('user_name', 'kenmarks', time() - 3600);

Session Variables

Session variables also allow the persistence of small pieces of data. However, instead of storing them on the client’s browser, they are stored on the server, giving them an added security benefit in preventing users from altering the data. They are also not limited to storing string data. You can persist arrays, variables, and serializable objects, and the PHP interpreter automatically converts them between scripts. However, session variables only last as long as the current web browsing session. In other words, the session ends when the user closes the browser. When the session ends, the $_SESSION variables are destroyed.

Using Session Variables with PHP

To use session variables, you must indicate when your session starts by using the function session_start():

1
session_start();

When first calling session_start(), there is no data saved. It only indicates that the PHP interpreter can start storing and accessing session variables and internally sets a unique identifier for this session. The web browser and our application use this unique identifier to associate a session with multiple web pages.

The session identifier is not destroyed until the session is closed. This happens when the web browser is closed or when you call the session_destroy() function:

1
session_destroy();

If you close a session yourself by using the session_destroy() function, it does not delete the session variables. Instead, it only ends the session.

When working with user data, you typically start a session when the user logs in, and you destroy the session when the user logs out.

To create session variables, you use the $_SESSION[] superglobal:

1
$_SESSION['user_name'] = 'kenmarks';

You use the session variable by accessing the $_SESSION superglobal using the assigned index to retrieve it’s value:

1
<p class="login">You are logged in as <?= $_SESSION['user_name'] ?>.</p>;

There are a few interesting things about using session variables. First, you must call the session_start() before creating and accessing session variables. Second, when hyperlinking from one page to another (or to the same page), you must remember that the web is stateless. To access any session variables you have created, you must call the session_start() function again.

The naming of session_start() is unfortunate. When developers first learn how to use session variables in PHP, they often assume that once they call session_start(), they do not need to call it again—even though the web is stateless. They wonder why they do not have access to their session variables in subsequent requests. A more accurate name for this function might be: session_start_or_resume().

Third, as mentioned above, calling session_destroy() only ends the session but does not delete the session variables. Until the user closes their browser and PHP’s session garbage collector deletes expired session data, you can’t depend on any data being deleted. To ensure session variables are deleted, set the $_SESSION[] superglobal to an empty array right after you destroy the session:

1
2
session_destroy();
$_SESSION = []; // Destroy all session variables in the current session

Working with Cookies and Session Variables

Cookies and session variables can coexist. One reason is that cookies can persist longer than session variables. However, since cookies live on the browser, they can be a security risk. One cookie that makes sense to have when using sessions is the session identifier (ID). This is because a user can have multiple tabs open into the same application. When you call session_start(), the session ID is sent as a cookie to the browser using a generated session name as the key. You get access to this session name for the current session by calling the session_name() function. When you are finished using any cookies, and you are ready to delete them, you also want to delete the session cookie using the session_name() function:

1
2
3
4
if (isset($_COOKIE[session_name()]))
{
    setcookie(session_name(), '', time() - 3600);
}

The Database

Of course, the database is one of the best tools we have for persisting data for as long as we want. I do not need to go into how to use the database here since you already know how to do that. Therefore, remember many of our persistence problems can be solved using the database. For example, you can persist a single ID as either a query parameter, a hidden form variable, a cookie, or a session variable, then use that ID to look up the pertinent information in the database.

Week 9 Lab