On the CD The scripts in this section will demonstrate the use of PHP and MySQL for authentication of users. You will find the code for the authentication project on the CD-ROM in the folder named chapter16code. The mini-application consists of six scripts:
createpasswordtable.php creates a stand-alone table with fields for user ID and for the password encrypted using the md5 program. The md5 program uses standard encryption techniques to produce a 32-character string.
register.php is a form and a form handler for accepting new IDs and passwords. If the ID already exists in the database, the user is prompted to try again.
signin.php is a form and a form handler for accepting an ID and a password. If the ID and password pair exist in the database, a session variable is set and the user can continue to a page of the application.
page.php essentially is a place holder for a real application. If users navigate to this page without signing in, they will see a message with a link telling them to go sign in. If they are signed in, as indicated by the presence of a session variable, they see a message indicating this and a link to sign out.
endsession.php says goodbye to the user and destroys the session.
showids.php would not be part of a regular application, but is produced here for you to use to examine the encrypted passwords.
Although the reasoning in this exposition was to produce a stand-alone system for you to study, it still would make sense when building an entire application to define a distinct table for IDs and passwords. You might detect that this table is part of the shopping cart application database. Notice that this code, shown in Table 16.1, resembles other code for creating MySQL tables. The records in the table have two fields.
<?php | Start PHP |
function createtable($tname,$fields) { | Header for function |
global $DBname, $link; | Use global values for database and link. Assumes connection has been made |
$query="CREATE TABLE ".$tname." (".$fields.")"; | Define query |
if (mysql_db_query($DBname,$query, $link)) { | Invoke query and test if it worked |
print ("The table, $tname, was created successfully.<br>\n");} | Print positive message |
else { | Else |
print ("The table, $tname, was not created. <br>\n");} | Print negative message: table was not created |
} | Ends function definition |
?> | End PHP |
<html><head><title>Creating password table </title></head><body> | HTML starting tags |
<?php | Start PHP |
require("opendbo.php"); | Connecting to database |
$tname = "ptable"; | Set name of table |
$fields="uid char(10) NOT NULL PRIMARY KEY, pass char(32)"; | Define fields |
createtable($tname, $fields); | Invoke function to create table |
mysql_close($link); | Close link |
?> | End PHP |
</body></html> | Closing HTML tags |
The register.php script, shown in Table 16.2, is invoked to establish a new user. Anyone can register as long as he or she choose a unique ID. The password is encrypted for storage in the database. Figure 16.1 shows how the screen looks after filling out the form.
Figure 16.1: Form for creating user ID and password.
<html><head><title>Registering</title></head><body> | Starting HTML tags |
<?php | Start PHP |
require("opendbo.php"); | Connecting code |
$tname = "ptable"; | Set name of table |
if (@($submitted)) { | If test to see if form has been submitted |
$pword1 = trim($pword1); | Trims the input (removing white space) |
$pword2 = trim($pword2); | Trims the input |
$uid = trim($uid); | Trims the input |
$oksofar = true; | Sets the oksofar variable, which might be set to false if there are any problems |
$pattern="^[a-z0-9]{4,10}$"; | Sets up a pattern specifying between 4 to 10 alphanumeric characters |
if (!eregi($pattern,$uid)){ | Does a case-insensitive test on the user ID |
print ("Please make your id a combination "); | If the test fails, prints instructions… |
print ("of at least 4 and not more than 10 alphanumeric characters. "); | ... continues with instructions |
print ("Use the BACK function on your browser to return to the form."); | More instructions |
$oksofar = false; | Sets the oksofar variable to false. |
} | End of clause for first test |
if (!eregi($pattern,$pword1)){ | Checks the first password for its format |
print ("Please make your password a combination "); | If the test fails, prints instructions… |
print ("of at least 4 and not more than 10 alphanumeric characters. "); | …continues with instructions |
print ("Use the BACK function on your browser to return to the form."); | More instructions |
$oksofar = false; | Sets the oksofar variable to false |
} | End of clause for test |
if (StrCmp($pword1,$pword2)!=0) { | Test to see if the user entered two identical copies of the password. This requires the use of the StrCmp function for comparison of strings |
print ("The two passwords did not match. Please try again. "); | If test fails, prints out message |
print ("Use the BACK function on your browser to return to the form."); | Prints out instructions |
$oksofar = false; | Sets the oksofar variable to false |
} | End of clause for test |
$query = "Select * from ptable where uid='$uid'"; | Define query to check if the user ID is already in the table |
$result=mysql_db_query($DBname, $query, $link); | Invoke query |
if (mysql_num_rows($result)!=0) { | If this query produced a recordset with more than zero rows—that is, there was an entry with that ID |
print ("The id is already taken. Please try again. "); | Print out message to try again. |
print ("Use the BACK function on your browser to return to the form."); | More instructions |
$oksofar = false; | Set oksofar variable to false |
} | End of clause for test |
if ($oksofar) { | If there have been no problems |
$pw1 = md5($pword1); | Encrypt the password. |
$query = "INSERT INTO $tname values ('$uid','$pw1')"; | Define a query to insert a new record in the table |
$result = mysql_db_query($DBname, $query, $link); | Invoke the query |
if ($result) { | Check on result |
print("Registration successful.<br>\n"); | Print positive message |
} | End of clause |
else { | Else |
print ("Registration not successful. <br>\n"); | Print negative message |
} | End of clause |
} | End of if no problems |
$submitted = FALSE; | Reset submitted variable |
mysql_close($link); | Close link |
} | ends if submitted |
else { | Else (present form) |
print ("<h1>Register<br>\n </h1> "); | Print out heading |
print ("Create a user id and a password. Make each a combination "); | Print out instructions |
print ("of at least 4 and not more than 10 alphanumeric characters. <br>"); | ….continue with instructions |
print ("<form action=\"register. php\" method=post>\n"); | Print out form tag |
print ("User name: <input type=text name=\"uid\" size=10><br>\n"); | Print out username tag (that is, user ID) |
print ("Password: <input type=password name=\"pword1\" size=10><br>\n"); | Print out input tag for password as a password tag so typing is not revealed |
print ("Enter password again: <input type=password name=\"pword2\" size=10><br>\n"); | Print out second input tag |
print ("<input type=hidden name=\"submitted\" value=\"True\"><br>\n"); | Print out hidden tag to hold submitted value |
print ("<input type=submit name=\"submit\" value=\"Sign up!\"><br>\n"); | Print out Submit button |
print ("</form><br>\n"); | Print out form end tag |
} | End of clause for form not submitted |
?> | Close PHP |
</body></html> | Closing HTML |
The script presents and handles the form. Note that several tests are done on the input.
The signin PHP script, shown in Table 16.3, is for a registered user to sign in, giving ID and password. Figure 16.2 shows the screen.
Figure 16.2: Form for signing in.
<?php | Start PHP |
if (@($submitted)) { | Check if form has been submitted |
$pword1 = trim($pword1); | Trim the password |
$uid = trim($uid); | Trim the user id |
$oksofar = true; | Set oksofar to true |
$pw1= md5($pword1); | Encrypt the submitted password |
require("opendbo.php"); | Connecting to the database |
$query = "Select * from ptable where uid='$uid' and pass='$pw1'"; | Define the query |
$result=mysql_db_query($DBname, $query, $link); | Invoke the query |
if (mysql_num_rows($result)==0) { | If test: checks for a match |
print ("No match for id and password. "); | If test fails, that is, there is no match, prints a message |
print ("Use the BACK function on your browser to return to the form."); | Prints instructions |
$oksofar = false; | Set oksofar variable to false |
} | Ends clause for test |
if ($oksofar) { | If there was a match, indicated by oksofar still being true |
session_register("user"); | Register user as a variable |
$user=$uid; | Set user to the value $uid |
print("Sign in okay as $user. <a href='page.php'>Continue. </a>"); | Print out message and give option to continue |
} | End clause |
$submitted = FALSE; | Set submitted variable to false |
mysql_close($link); | Close link |
} | ends if submitted |
else { | Else clause (to present a form) |
?> | Ends PHP |
<html><head><title>Sign in</title></head><body> | Regular HTML tags |
<h1>Sign in<br></h1> | Heading |
<form action="signin.php" method=post> | Form with action indicated as this script |
User name: <input type=text name="uid" size=10><br> | User field |
Password: <input type=password name=”pword1” size=10><br> | Password field |
<input type=hidden name="submitted" value="True"><br> | Hidden tag (submitted flag) |
<input type=submit name="submit" value="Sign up!"><br> | Submit button |
</form><br> | End of form |
<? | Start PHP |
} | End the clause for form to be |
displayed | |
?> | End PHP |
</body></html> | Closing HTML tags |
This script both handles and presents a form. Notice that the typical HTML starting tags are not placed at the start of the script. This is required since the code to set the session variable must precede any output.
The page.php script, shown in Table 16.4, is a placeholder for the first page of an application. Note that it starts the session explicitly using the session_start function. This really means start or resume a session. It was not necessary in the signin.php script because the session_register function started the session.
<?php | Start PHP |
session_start(); | Resume or start the session |
if (!session_is_registered("user")) { | Check if user exists as a session variable |
?> | End PHP |
You need to <a href="signin.php">SIGN IN.</a> | Print message and link for the visitor to sign in |
<? | Restart PHP |
} | End clause for there not being a registered user |
else { | Else clause |
print("<html><head><title>First page </title></head><body>"); | Print out starting HTML tags |
print ("You are signed in. User id is $user"); | Print out message to user |
print ("<br><a href=\"endsession.php\">Sign out and end session </a>"); | Print out option to sign out |
} | End clause for there being a user |
?> | End PHP |
</body></html> | HTML closing tags |
Figure 16.3 shows what page.php produces when the user has signed in.
Figure 16.3: Screen showing successful sign in.
The endsession.php script, shown in Table 16.5, signs the user out by printing a goodbye message and destroying the session. In a real application, you should insert similar code either in a script by itself or as part of other scripts. This protects any user who does not exit the browser after completing his or her business. Figure 16.4 shows what endsession.php produces.
Figure 16.4: Screen showing goodbye message.
<?php | Start PHP |
session_start(); | Start or resume session |
print("Good-bye, $user."); | Print out message, making use of the session variable $user |
session_destroy(); | Destroy session |
?> | End PHP |
</body></html> | Closing HTML tags |
The showids.php script, shown in Table 16.6, is to show you the state of the password table.
<html><head><title>Show ids and passwords</title></head><body> | Starting HTML tags |
<h1>Id and encrypted passwords</h1><p> | Heading |
<?php | Start PHP |
require ("opendbo.php"); | Connecting to database |
?> | End PHP |
<table border=1> | Table tag |
<?php | Start PHP |
$query="Select * from ptable"; | Define query to get the entire table |
$result=mysql_db_query($DBname, $query, $link); | Invoke query |
while ($row=mysql_fetch_array($result)) { | While loop: iterates over the entire recordset, fetching a row at a time |
print ("<tr><td>"); | Print out table tags |
print($row['uid']); | Print out the uid field |
print("</td>"); | Print out table datum close tag |
print("<td>"); | Print out table datum start tag |
print($row['pass']); | Print out the pass field |
print("</td></tr>"); | Print out the table tags closing the row |
} | Ends while loop |
print ("</table>"); | Print out table closing tag |
mysql_close($link); | Close link |
?> | End PHP |
</body></html> | Closing HTML tags |
Figure 16.5 shows the display of the password table.
Figure 16.5: Display of IDs and encrypted passwords.
Can you guess either of the passwords?