User Authentication for a Project Management Application

In the last article, we discussed in detail the user creation script. We looked at what information the script gets from the form and how it "cleans" and verifies form values, and then looked at how the user is informed about his or her log-in credentials. In this article, the conclusion to our four-part series, we’ll finish the discussion.

The remaining part of the user creation script is the form in which the administrator inserts all the data about the user. The first block of HTML code displays the logged-in user name plus an option to log out, and also sets the page title. Both are marked in red below.


<!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/admin.dwt.php"


codeOutsideHTMLIsLocked="false" –>

<head>

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

<!– InstanceBeginEditable name="doctitle" –>

<title>Project Management</title>

<!– InstanceEndEditable –>

<!– InstanceBeginEditable name="head" –>

<!– InstanceEndEditable –>

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

</head>


<body>

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

<tr>

<td width="38%">&nbsp;</td>

<td width="22%">&nbsp;</td>

<td width="40%">Logged in:<!– InstanceBeginEditable name="EditRegion4" –><? echo $_SESSION['name'];?> | <a

href="../logout.php">Logout</a>

<!– InstanceEndEditable –></td>

</tr>

<tr>

<td colspan="3" bgcolor="#6699CC"><span class="headertxt"> Project Management Software -Administration </span></td>

</tr>

<tr>

<td colspan="3"><!– InstanceBeginEditable name="EditRegion3" –>

The next block creates and displays the form and crucially, sets the error message display area (again, both are highlighted in red for ease of identification).

<form name="form1" action="add_user.php" method="post">

<table width="657" border="0" class="formborder">

<tr>

<td colspan="2" class="loginheader">Create New User </td>

</tr>

<tr>

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

</tr>

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

<tr>

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

</tr>

<tr>

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

</tr>

<tr>

<?php

}

?>

{mospagebreak title=User Information}

The error message is only displayed if it is not empty; otherwise, the entire row of the table is hidden from the user. The remainder of the code collects further information about the user, such as the email address, username, password and other required information.

<tr>

<td width="122"><div align="left">Name:</div></td>

<td width="525"><input name="fname" type="text" class="input40" size="40"></td>

</tr>

<tr>

<td width="122"><div align="left">Surname:</div></td>

<td width="525" class="login"><input name="sname" type="text" size="40"></td>

</tr>

<tr>

<td width="122"><div align="left">Username:</div></td>

<td width="525" class="login"><input name="uname" type="text" size="40">

<span class="tooltip">username must be in format: <strong>name.surname</strong></span></td>

</tr>

<tr>

<td width="122"><div align="left">Password:</div></td>

<td width="525" class="login"><input name="upass" type="text" size="40" value="<?php echo $rndpass; ?>"></td>

</tr>

<tr>

<td><div align="left">Email:</div></td>

<td class="login"><input name="email" type="text" size="40"></td>

</tr>

<tr>

<td><div align="left">Access Level</div></td>

<td class="login"><label>

<select name="select">

<option>admin</option>

<option>normal</option>

</select>

</label></td>

</tr>

Here is the code for the row that collects the password information:

<tr>

<td width="122"><div align="left">Password:</div></td>

<td width="525" class="login"><input name="upass" type="text" size="40" value="<?php echo $rndpass; ?>"></td>

It can be hidden from the administrator and sent directly to the newly created user. This way, only the user will know what his or her password is. I’ve left this option open for you to decide what to do based on your situation.

The user can access the password recovery script by clicking on the “forgot your password?” link on the login page. See the screen below:


Fig. 1 login page with the “forgotten password?” link.


Fig. 2 password recovery page

The password script handles the password recovery process, in case the user forgets his or her password. It will ask the user for the username and an email address. To prevent fraud, the script will check to see if the username and email address exists in the database and that they both belong to the same person. Only after it is satisfied that it belongs to the same person will it then email the password to the given email address.

So let’s look at the code that does the work. Click on the link below to see it. 

{mospagebreak title=The Script}


Script: password.php

<?php

session_start();

include "dbcon.php";

include "functions.php";

//initialise variables

$err="";

$errmsg=false;


//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";

$err=true;

}

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

$err=true;

$errmsg .="The email address field is empty, please enter a email address";

}


//check that the username is in correct format

if(!$err){

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

$err=true;

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

}

}


//check that the email is in correct format

if(!$err){

if(!checkmailformat($_POST['email'])){

$err=true;

$errmsg .="The email address that you entered has a incorrect format.";

}

}



//check to see if the user exist

if(!$err){

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

$cleanemail = mysql_escape_string($_POST['email']);

$unamecheck = "SELECT email,name,sname FROM users WHERE username=’".$cleanuname."’ and email = ‘".$cleanemail."’";

$result=mysql_query($unamecheck);

$num=mysql_num_rows($result);

if($num > 0){

$row = mysql_fetch_assoc($result);

$thepass = $row['upass'];

$theName = $row['name'];

//build email headers

//this text will appear in the subject line of the email

$subject = "Project Management – Password Recovery";

//this is the recipient of the email

$to = $cleanemail;

//sender name

$from_name = "Project Management Application";

//sender address

$from_email = "website@mywebsite.com";

$headers = "From: " . $from_name . " <" . $from_email . ">";

//build message

$msg = "<html>

<head>

<title>Project Management</title>

<link rel=’stylesheet’ type=’text/css’ href=’http://www.yourwebsitelocationhere.com/loginstyle.css’>

</head>

<body>

<table width=’100%’ border=’0′ cellspacing=’0′ cellpadding=’0′>

<tr>

<td><p>Dear <b>".$theName."</b></p>

Below is the password you requested:<br />

<br />

<b>Password:</b> ".$thepass.";


</td>

</tr>

</table>";

$msg .= "</body>

</html>";


mail($to, $subject, $msg, $headers);

}else{

$err=true;

$errmsg .="The information you entered is incorrect or does not exists. ";


}

}




}//end submit

?>


<!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>Untitled Document</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" –>

<form id="form1" name="form1" method="post" action="">

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

<tr>

<td colspan="2" class="loginheader">Password Recovery </td>

</tr>

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

<tr>

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

</tr>

<tr>

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

</tr>

<tr>

<?php

}

?>

<tr>

<td>Username:</td>

<td><label>

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

</label></td>

</tr>

<tr>

<td>Email Address: </td>

<td><label>

<input name="email" type="text" id="email" size="40" />

</label></td>

</tr>

<tr>

<td>&nbsp;</td>

<td><label>

<input name="submit" type="submit" id="submit" value="Get Password" />

</label></td>

</tr>

</table>

</form>

<!– InstanceEndEditable –></td>

</tr>

<tr>

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

</tr>

</table>

</body>

<!– InstanceEnd –></html>

Let’s look at the PHP code in detail. After including the database connection files, and initializing some variables, the code runs the usual checks on the form values.

session_start();

include "dbcon.php";

include "functions.php";

//initialise variables

$err="";

$errmsg=false;


//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";

$err=true;

}

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

$err=true;

$errmsg .="The email address field is empty, please enter a email address";

}


//check that the username is in correct format

if(!$err){

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

$err=true;

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

}

}


//check that the email is in correct format

if(!$err){

if(!checkmailformat($_POST['email'])){

$err=true;

$errmsg .="The email address that you entered has a incorrect format.";

}

}

We continue our analysis of the code in the next section.

{mospagebreak title=Checking the User and Email}

After running the initial checks on the form values, the code gets to the most important bit of the program, which is to see if the user and email address actually exists in the database. Remember, anyone can enter any email address with the correct username and try to get the password sent to an email address that is not connected to the username. Therefore, in this program, we will guard against this tactic by checking (in the database) to see if the username and email address entered are connected:

if(!$err){

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

$cleanemail = mysql_escape_string($_POST['email']);

$unamecheck = "SELECT email,name,sname FROM users WHERE username=’".$cleanuname."’ and email = ‘".$cleanemail."’";

$result=mysql_query($unamecheck);

$num=mysql_num_rows($result);

if($num > 0){

$row = mysql_fetch_assoc($result);

$thepass = $row['upass'];

$theName = $row['name'];

Once we’ve established that the password actually belongs to the person requesting it, we then proceed to create a email message, and send the password to the email address provided.

//build email headers

//this text will appear in the subject line of the email

$subject = "Project Management – Password Recovery";

//this is the recipient of the email

$to = $cleanemail;

//sender name

$from_name = "Project Management Application";

//sender address

$from_email = "website@mywebsite.com";

$headers = "From: " . $from_name . " <" . $from_email . ">";

//build message

$msg = "<html>

<head>

<title>Project Management</title>

<link rel=’stylesheet’ type=’text/css’ href=’http://www.yourwebsitelocationhere.com/loginstyle.css’>

</head>

<body>

<table width=’100%’ border=’0′ cellspacing=’0′ cellpadding=’0′>

<tr>

<td><p>Dear <b>".$theName."</b></p>

Below is the password you requested:<br />

<br />

<b>Password:</b> ".$thepass.";


</td>

</tr>

</table>";

$msg .= "</body>

</html>";


mail($to, $subject, $msg, $headers);

}else{

If the information that the user provides does not match up, we set the appropriate error message and display it in the password form.

$err=true;

$errmsg .="The information you entered is incorrect or does not exists. ";


}

}

}//end submit

Like the other forms, the password form allows a space on the form to display the error message. 

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

<tr>

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

</tr>

<tr>

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

</tr>

<tr>

<?php

}

?>

Conclusion

That is all there is to the user authentication system for the project management application. I am sure there are some things that can be improved, and no doubt some of you will do so. We’ve covered a lot of ground in the last couple of articles dealing with user authentication and I hope that it will give some of you more ideas on how to make your login scripts more secure.

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

chat