PHP Index

About

This is an authentication script for PHP based on flat files (i.e. no database).

Directory Structure

/var/www/localhost/htdocs is our web application document root.

/var/www/localhost/htdocs/db is our flat-file database location.

/var/www/localhost/htdocs/db/users/passwd is the file that contains the user information. Users are listed as username:CRYPT_BLOWFISH where the CRYPT_BLOWFISH is the actual hash.

/var/www/localhost/htdocs/db/sessions/ is the directory that contains our authentication files. Should clean this directory up often. The files are prefixed with the date and time for natural sorting. These files are named with a blowfish hash and contain various things based on the user like session id, username and date logged in.

Functions

The following functions are used to read and write the flat-files. The ws_touch() function should be used when creating files and must be used before ws_write_file().

function ws_touch($file)
{
        $fp = fopen($file,"w");
        if(flock($fp,LOCK_EX))
        {
                fwrite($fp,"");
                flock($fp,LOCK_UN);
                fclose($fp);

                return 1;
        }
        else
        {
                ### todo: handle the case where we don't get a lock
               return 0;
        }
}

function ws_read_file($file,$var)
{
        $var = trim($var);
        $a_file = file($file);
        foreach($a_file as $line)
        {
                if(preg_match("/^{$var}:?/",$line))
                {
                        $pattern = array(
                                "/^{$var}:?(.*)$/",
                                "/(\r\n|\r|\n)$/"
                                );
                        $replacement = array(
                                "$1",
                                ""
                                );
                        $var_value = preg_replace($pattern,$replacement,$line);
                }
        }
        trim($var_value);

        return $var_value;
}

function ws_write_file($file,$var,$var_value)
{
        if(file_exists($file))
        {
                $eol = "\n";
                $is_match_found = "no"; ### if $var is not found, we'll append to the end of the file.
               $var = trim($var);
                $var_value = trim($var_value);
                $a_pattern = array("/\r\n/","/\r/","/\n/");
                $a_replacement = array("%0a","%0a","%0a");
                $var = preg_replace($a_pattern,$a_replacement,$var);
                $var_value = preg_replace($a_pattern,$a_replacement,$var_value);
                $newfile = ""; ### this will be written to the file
               $a_file = file($file);
                foreach($a_file as $line)
                {
                        if(preg_match("/^{$var}:/",$line))
                        {
                                $is_match_found = "yes";
                                $line = "{$var}:{$var_value}" . $eol;
                        }

                        $newfile .= $line;
                }

                if($is_match_found == "no")
                {
                        $newfile .= "{$var}:{$var_value}" . $eol;
                }

                file_put_contents($file,$newfile);

                return 1;
        }
        else
        {
                return 0;
        }
}

function ws_register_var($var,$desc)
{
        $file = "db/variables/registered_variables";
        if(!file_exists($file))
        {
                if(!ws_touch($file))
                {
                        return 0;
                }
        }

        if(ws_read_file($file,$var) == '')
        {
                ws_write_file($file,$var,$desc);

                return 1;
        }
        else
        {
                return 0;
        }
}

I've added the ws_register_var() function so that variables are not overlapping. If you have a doubt about what variable to use, you'd look in the file it generates.

The basic use of ws_register_var() is

<?php
ws_register_var("variable_name","A description about the variable");
?>

It will append the variable name and description to the file /var/www/localhost/htdocs/db/variables/registered_variables. The function returns 0 if the variable is already in that file.

To create a file, use

<?php
ws_touch("/path/to/file");
?>

To read a variable in a file, use

<?php
ws_read_file("/path/to/file","variable_name");
?>

To write a variable to a file, use

<?php
ws_write_file("/path/to/file","variable_name","new variable value");
?>

How to Install

Create the following directories in your document root.

/var/www/localhost/htdocs/db
/var/www/localhost/htdocs/db/users
/var/www/localhost/htdocs/db/sessions

Add the file passwd to the directory /var/www/localhost/htdocs/db/users.

If you have the command line interface (CLI) for php, open a terminal and execute the following command.

$ echo "<?php print(crypt("mypassword",CRYPT_BLOWFISH)); ?>" | php

outputs

0$OZrQY.c10sY

This will give you the hash for your password. Now you can add the following line to the /var/www/localhost/htdocs/db/users/passwd file.

yourusername:0$OZrQY.c10sY

Form for users to submit username and password

I put this code in the document root and in my index.php file.

<?php
if($action == "login" && $formsent != "yes" && $is_logged_in == "no")
{
        $login_form = <<<eof
<form name="login_form" action="{$phpself}?action=login&formsent=yes" method="post">
<label>Username</label><br />
<input class="field" type="text" name="f_username" value="" />
<br /><br />
<label>Password</label><br />
<input class="field" type="password" name="f_password" value="" />
<br /><br />
<input class="button" type="submit" value="Login" />
</form>
eof
;
        $html_body_output = $login_form;
}
?>

Script that processes the form input

<?php
### start: check for session ###
session_start();
$sessid = session_id();
if(file_exists("db/sessions/{$sessid}"))
{
        $is_logged_in = "yes";
}
else
{
        $is_logged_in = "no";
}
### end: check for session ###

### start: prepare html body ###
### process login ###
if($action == "login" && $formsent == "yes" && $is_logged_in == "no")
{
        if($f_username != '' && $f_password != '')
        {
                $f_password_hash = crypt($f_password,CRYPT_BLOWFISH);
                $real_password_hash = ws_read_file("db/users/passwd","wsams");

                if($f_password_hash == $real_password_hash)
                {
                        $is_logged_in = "yes";
                        if(!file_exists("db/sessions/{$sessid}"))
                        {
                                if(!ws_touch("db/sessions/{$sessid}"))
                                {
                                        ### todo: show a message saying the file could not be written.
                               }
                                ws_write_file("db/sessions/{$sessid}","sessid",$sessid);
                                ws_write_file("db/sessions/{$sessid}","username",$f_username);
                                ws_write_file("db/sessions/{$sessid}","timestamp",date("Y-m-d H:i:s"));
                        }

                        header("Location:{$phpself}"); exit();
                }
                else
                {
                        $is_logged_in = "no";
                }
        }
}
?>

Page Comments (Click to edit)






[Click to add or edit comments])

Please prepend comments below including a date

Design by N.Design Studio, adapted by solidGone.org (version 1.0.0)
Have a nice day.