Project Management: Authentication

I recently completed an article series in which we built a project management application. Every application that wants to control access to its resources has an access control mechanism that will verify if a user is allowed to use the particular application. A project management application is a good candidate for such a control. In this four-part series, we will build an authentication system for the application.

There may be any number of reasons an application needs to control access. For example, the application may need to grant certain privileges to some and different ones to others. It can also be that the application simply wants to keep track of the user.

In our application, we want to keep track of the user in addition to making sure that a user is actually allowed to use the application. And we also grant different levels of security or access for different users, to sections of the application. The application has an administration section that will make use of this access control, as you will see later on.


How it works:


As the diagram shows, the user is presented with an HTML login form that has the username and password fields. Once the user enters the required username and password, PHP tries to match the password and username that the user entered to the username and password in the database.

If it finds a match, the user is granted access to the Project Management application; if it does not find a match, the user is redirected to the HTML login form with a error message saying that the username or password did not match. Before we go on to look at the code that enables this to happen, let’s look at the users table. It holds the user login credentials.

The Database Table

Let’s look at the requirements for a table that will hold the user log-in information. Any user that wants to use our application needs to have a username and password. These are the key log-in details that are required. I’ve decided that the username must have the following format:


name.surname


This is because I want to make it that little bit harder for a hacker to get access to the application. We need the name and surname of the user. This is because the application assumes that it will be used in an intranet environment, where different members of the company will access it, to check on the progress of projects in which they are interested. The application will be able to address the user by his or her name, when it needs to, instead of a username that is not really appropriate.

A user will also need application level access that will enable them to create projects and users. To create a project is natural in an application that is designed for it, but to create users will require a higher level of access, simply because creating a user involves the two key aspects of user authentication: the username and more importantly the password. And if we just allow any user to create new users, then the system will not be secure. So it is essential that only certain people have the right to do so.

This is why I created two levels of access, “admin” and “normal.” The “admin” access level has no restrictions, while, as you’d expect, the “normal” access level does. If a user forgets his or her password, we need some way of getting the password to him or her. In that case, we need to have an email address for the user. So based on the above considerations, our “users” table should have the following fields:


username – The username with format name.surname

password – a seven character password is automatically generated

name – name of user

surname – surname of user

level – access level is either admin or normal

email – user email address, in case the pass word is forgotten

last_login – date of last log-in

{mospagebreak title=Create the Table}

So create a table with the following SQL:

CREATE TABLE `users` (

`uid` int(11) NOT NULL auto_increment,

`name` varchar(20) NOT NULL default ”,

`sname` varchar(20) NOT NULL default ”,

`uname` varchar(100) NOT NULL default ”,

`upass` varchar(8) NOT NULL default ”,

`level` enum(‘admin’,’normal’) NOT NULL default ‘normal’,

`last_login` datetime NOT NULL default ‘0000-00-00 00:00:00′,

`email` varchar(100) NOT NULL default ”,

PRIMARY KEY (`uid`)

) TYPE=MyISAM AUTO_INCREMENT=5 ;



Below is some sample data for the table:


INSERT INTO `users` VALUES (1, ‘jack’, ‘dee’, ‘jack.dee’, ‘pass’, ‘admin’, ‘0000-00-00 00:00:00′, ‘jack@dee.com’);

INSERT INTO `users` VALUES (2, ‘maria’, ‘garises’, ‘maria.garises’, ‘pass’, ‘normal’, ‘0000-00-00 00:00:00′, ‘maria@garises.com’);

INSERT INTO `users` VALUES (3, ‘kine’, ‘brand’, ‘kine.brand’, ‘pass’, ‘normal’, ‘0000-00-00 00:00:00′, ‘kine@brand.com’);

INSERT INTO `users` VALUES (4, ‘john’, ‘doe’, ‘john.doe’, ‘pass’, ‘normal’, ‘0000-00-00 00:00:00′, ‘john@doe.com’);


Copy and paste the above SQL in your MySQL administration application and run it. You should have a table called "users" with the sample data above. Now, let’s create the login script that will run the login process for us. Create a new PHP document and add the following code:


<?php

include "dbcon.php";

include "functions.php";

//initialise variables

$err=false;

$errmsg=””;


//is form submitted?

if(isset($_POST['submit'])){

//check that the form values are not empty, if so, set errormsg value

if(empty($_POST['uname'])){

$errmsg="The username field is empty, please enter a username<br>";

$err=true;

}

if(empty($_POST['upass'])){

$err=true;

$errmsg .="The password field is empty, please enter password<br>";

}


//check that the username is in correct format

if(!checkformat($_POST['uname'])){

$err=true;

$errmsg .="The username that you entered has a incorrect format.<br>";

}



//if there is no errors above, then clean the form values before using in query.

if(!$err){

$cleanuname = mysql_escape_string($_POST['uname']);

$cleanupass = mysql_escape_string($_POST['upass']);


$checkuser = "SELECT * from users WHERE uname = ‘".$cleanuname."’ AND upass = ‘".$cleanupass."’";

$checkuser_res = mysql_query($checkuser);

$checkuser_num = mysql_num_rows($checkuser_res);


if($checkuser_num > 0){

//if user exists and passes authentication

//setup session variables and redirect to index page

$row = mysql_fetch_assoc($checkuser_res);

$_SESSION['name'] = $row['name']." ".$row['sname'];

$_SESSION['uid'] = $row['uid'];

$_SESSION['level'] = $row['level'];


//redirect

header("location:main.php");

}else{

//if values do not match set errmsg

$err=true;

$errmsg .="The username or password you entered does not match.<br> MYSQL ERROR ".mysql_error();

}//else


}//end $err check


} //end form submit check


?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"><!– InstanceBegin template="/Templates/userauth.dwt.php" codeOutsideHTMLIsLocked="false" –>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<!– InstanceBeginEditable name="doctitle" –>

<title>Project Management ::Login</title>

<!– InstanceEndEditable –>

<!– InstanceBeginEditable name="head" –><!– InstanceEndEditable –>

<link href="Templates/loginstyle.css" rel="stylesheet" type="text/css" />

</head>


<body>

<table width="100%" border="0">

<tr>

<td bgcolor="#6699CC" class="headertxt">Project Management:: User Authentication </td>

</tr>

<tr>

<td><!– InstanceBeginEditable name="main" –>

<table width="100%" border="0" class="formborder">

<tr>

<td colspan="2" class="loginheader">Login</td>

</tr>

<tr>

<td colspan="2">&nbsp;</td>

</tr>

<form action="login.php" method="post" name="f1" class="formborder">

<?php if(isset($errmsg)){?>

<tr>

<td colspan="2" class="errmsg" ><?php echo $errmsg; ?></td>

</tr>

<tr>

<td colspan="2">&nbsp;</td>

</tr>

<tr>

<?php

}

?>

<td width="10%" valign="bottom"><strong>Username:</strong></td>

<td width="90%"><label>

<input name="uname" type="text" class="login" id="uname" size="40" />

</label></td>

</tr>

<tr>

<td valign="bottom"><strong>Password:</strong></td>

<td><label>

<input name="upass" type="password" class="login" id="upass" size="40" />

</label></td>

</tr>

<tr>

<td>&nbsp;</td>

<td><a href="password.php">Forgot your password?</a> </td>

</tr>

<tr>

<td>&nbsp;</td>

<td><label>

<input name="submit" type="submit" id="submit" value="Log me in!" />

</label></td>

</tr>

</form>

</table>

<!– InstanceEndEditable –></td>

</tr>

<tr>

<td align="right" class="cright">copyright &copy; 2007 PM </td>

</tr>

</table>

</body>

<!– InstanceEnd –></html>




{mospagebreak title=The Login Code}

The first couple of lines includes the database connection file, which contains our database connection credentials, and also the functions file, which contains the functions that we are going to use for user verification. Some of the lines also enable us to initialize variables:


include "dbcon.php";

include "functions.php";

//initialise variables

$err=false;

$errmsg=””;


The $err and $errmsg variables are used to collect error messages across the script, and depending on whether there are errors, will be displayed on the login form. The $err variable is of type Boolean, and is initially set to false. In most of the scripts in this application, it will decide whether or not SQL queries can be run. The next couple of lines basically checks to see if the form has been submitted:


//is form submitted?

if(isset($_POST['submit'])){


Then tests to see if the form fields are empty or not:


//check that the form values are not empty, if so, set errormsg value

if(empty($_POST['uname'])){

$errmsg="The username field is empty, please enter a username<br>";

$err=true;

}


If they are empty, the $err variable is set to true and the $errmsg variable is assigned a error message:


if(empty($_POST['upass'])){

$err=true;

$errmsg .="The password field is empty, please enter password<br>";

}


Another test is performed on the username that is submitted. The test is to verify that the username is in the correct format. Remember that our usernames must be in the format name.surname:


//check that the username is in correct format

if(!checkformat($_POST['uname'])){

$err=true;

$errmsg .="The username that you entered has a incorrect format.<br>";

}


The checkformat() function is located in the functions.php file and has the following code:


function checkformat($aUsername){

if(eregi(‘^[a-z]+[.]+[a-z]+$’,$aUsername))

return TRUE;

else

return FALSE;

}


It makes use of regular expression by matching a pattern against a given string value. You can of course use other ways to verify the username format.

{mospagebreak title=Login Code continued}

After testing to see if the fields are empty, and verifying the username format, the code goes on to run a check in the database to try to match the username and password entered by the user, after escaping the form data:

//if there is no errors above, then clean the form values before using in query.

if(!$err){

$cleanuname = mysql_escape_string($_POST['uname']);

$cleanupass = mysql_escape_string($_POST['upass']);


As the code above shows, the two form values are escaped using the mysql_escape_string() function. This function gets rid of any white spaces or slashes that may be in the form values, and thus cleans the values for use in a MySQL query. This kind of filtering is very important when running queries, as it closes any security vulnerabilities that may otherwise occur. Next the code runs the MySQL query to actually compare the information from the form with the data in the database:


$checkuser = "SELECT * from users WHERE uname = ‘".$cleanuname."’ AND upass = ‘".$cleanupass."’";

$checkuser_res = mysql_query($checkuser);


The outcome of the check is stored in the $check_user variable, which will contain a value that is greater than zero if there’s a match and a value that is less than zero if there is not a match:


$checkuser_num = mysql_num_rows($checkuser_res);

if($checkuser_num > 0){


The code above checks to see if there is a match by finding out if the value returned by the query is greater than zero. If so, we transfer user details to the session variables. The session has already been started by the inclusion of the dbcon.php file that contains the session_start() function. The name, user id and access level of the user are stored in the session variables, then the user is granted access to the application. From this point on the user will be tracked:


//if user exists and passes authentication

//setup session variables and redirect to index page

$row = mysql_fetch_assoc($checkuser_res);

$_SESSION['name'] = $row['name']." ".$row['sname'];

$_SESSION['uid'] = $row['uid'];

$_SESSION['level'] = $row['level'];


//redirect

header("location:main.php");


If the user details do not match, the $errmsg variable is assigned an error message which is then displayed on the log-in form:


}else{

//if values do not match set errmsg

$err=true;

$errmsg .="The username or password you entered does not match.<br> MYSQL ERROR ".mysql_error();

}//else


}//end $err check


} //end form submit check


Conclusion

The next article will finish off the section on user log-in and log out.

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort