PHP: User Authentication

Derek Bridge

Department of Computer Science,
University College Cork

PHP: User Authentication

Aims:

The full system: authentication.zip
(Remember to edit $host, $user, $password and $dbname)

Options

How to restrict access to certain content

HTTP authentication
As for the CompSci internal web site:
  • Configure the server to send a 401 response to the client
  • The client prompts the user for a password, and sends it back to the server
PHP authentication by IP address
Your script can check whether the client's IP address is allowed to access the content
PHP authentication using a database of user names and passwords

MySQL database for user authentication

CREATE TABLE users 
(
    username VARCHAR(30) NOT NULL,
    password VARCHAR(32) NOT NULL,
    PRIMARY KEY (username)
);

Overview of the scripts

[The scripts used in our authentication system]

index.php

register.php: pseudocode

register.php: the PHP

<?php 
    require_once( 'output_functions.php' );
    require_once( 'validation_functions.php' );
    
    function output_form_page( &$errors )
    {
        output_header('Rodents Reunited: Registration', 'rr.css');    
        echo "<form action=\"{$_SERVER['PHP_SELF']}\" method=\"post\">";
        output_textfield('username', 'User name: ', 'username', 30, 30, 
                isset($_POST['username']) ? $_POST['username'] : '', false);
        output_passwordfield('password1', 'Password: ', 'password1', 10, 10, '', false);
        output_passwordfield('password2', 'Re-enter password: ', 'password2', 10, 10, '', false);
        output_submit_button('Register'); 
        output_reset_button('Reset');
        if ( count($errors) > 0 )
        {
            output_unordered_list( array_values($errors) );
        }
        echo "</form>";
        output_footer('Rodents Reunited Inc.');    
    }
    
    function output_problem_page()
    {
        output_header('Rodents Reunited: Problem', 'rr.css'); 
        output_paragraph( 'We are undergoing scheduled maintenance.' );
        output_footer('Rodents Reunited Inc.'); 
    }

    function is_initial_request()
    {
        return ! isset($_POST['submit']);
    }
    
    $errors = array();
    if ( is_initial_request() )
    {
        output_form_page( $errors );
    }
    else
    {
        // Connect to database
        $dbconnection = mysqli_connect( $host, $user, $password, $dbname );
        if ( ! $dbconnection )
        {
            output_problem_page();
            die();
        }
   
        // Get user's data
        $username = get_required_string( 
            $_POST, 'username', 'Username', 30, $errors );
        $password1 = get_required_string(
            $_POST, 'password1', 'Password', 10, $errors );
        $password2 = get_required_string(
            $_POST, 'password2', 'Copy of password', 10, $errors );
        if ( $password1 != $password2 )
        {
            $errors['password1'] = 'Passwords must be equal';
        }
        // Check whether this user name is in use
        if ( $username != NULL )
        {
            $sql_retrieve = "SELECT * FROM users WHERE username = '{$username}'";
            $dbretrieve_result = mysqli_query( $dbconnection, $sql_retrieve );
            if ( ! $dbretrieve_result )
            {
                output_problem_page();
                mysqli_close( $dbconnection );
                die();
            }
            if ( mysqli_num_rows( $dbretrieve_result ) > 0 ) 
            {
                $errors['username'] = "Username not available";
            }
            mysqli_free_result( $dbretrieve_result );            
        }
        if ( count( $errors ) > 0 )
        {
            output_form_page( $errors );
        }
        else
        {
            // One-way encrypt the password
            $md5_password = md5( $password1 );          

            // Store the new user's details
            $sql_insert = "INSERT INTO users (username, password) 
                           VALUES ('{$username}', '{$md5_password}');";
            $dbinsert_result = mysqli_query( $dbconnection, $sql_insert );
            if ( ! $dbinsert_result )
            {
                output_problem_page();
                mysqli_close( $dbconnection );
                die();
            }
            // All is well with this new user
            // Store his/her name in the session store and show links to the protected content!
            session_start();
            $_SESSION['authenticated'] = true;
            $_SESSION['username'] = $username;
            output_header( 'Rodents Reunited: Members only content', 'rr.css' );
            output_paragraph( 'Thanks for joining Rodents Reunited' );
            $menu = array('<a href="wombats.php">Wombat Lovers\' Corner</a>', 
                      '<a href="squirrels.php">Squirrel Lovers\' Corner</a>');
            output_unordered_list( $menu );
            output_footer( 'Rodents Reunited Inc.' );
        }
        mysqli_close( $dbconnection );        
    }
?>

login.php: pseudocode

wombats.php/squirrels.php: the 'protected' content

wombats.php/squirrels.php: the 'protected' content

<?php
    require_once( 'output_functions.php' );
    
    session_start();
    if ( ! isset($_SESSION['authenticated']) ) 
    {
        // Here output a permission denied page
        die();
    }
    // Here output the 'protected' content and a hyperlink to logout.php
?>

logout.php