In Chapter 12, "Working with Cookies and User Sessions," you learned all about the structure of a cookie and how to set and access cookie variables in PHP. The next few sections show some practical uses of cookies for authentication purposes.
Suppose that you created a login form that checked for values against a database. If the user is authorized, you send a cookie that says as much. Then, for all pages you want to restrict only to authorized users, you check for the specific cookie. If the cookie is present, the user can see the page. If the cookie is not present, the user is either sent back to the login form, or a message regarding access restrictions can be printed to the screen.
We'll go through each of these steps in the next few sections.
Creating the Authorized Users Table
When you're integrating user accounts into a web-based application, it is common to store the user-specific information in a database table. The information in this table can then be used to authorize the user and grant access to areas of the site specifically for these "special" users.
The following table creation command will create a table called auth_users in your MySQL database, with fields for the ID, first name, last name, email address, username, and password:
mysql> CREATE TABLE auth_users ( -> id int NOT NULL PRIMARY KEY AUTO_INCREMENT, -> f_name VARCHAR(50), -> l_name VARCHAR(50), -> email VARCHAR(150), -> username VARCHAR(25), -> password VARCHAR (75) -> ); Query OK, 0 rows affected (0.03 sec)
The following INSERT command puts a record in the auth_users table for a user named John Doe, with an email address of firstname.lastname@example.org, a username of jdoe, and a password of doepass:
mysql> INSERT INTO auth_users VALUES ('1', 'John', 'Doe', 'email@example.com', -> 'jdoe', PASSWORD('doepass')); Query OK, 1 row affected (0.00 sec)
This INSERT command should be self-explanatory, with the exception of the use of the PASSWORD() function. When this function is used in the INSERT command, what is stored in the table is in fact not the actual password, but a hash of the password.
When you view the contents of the auth_users table, you will see the hash in the password field, as follows:
mysql> select username, password from auth_users; +----------+-------------------------------------------+ | username | password | +----------+-------------------------------------------+ | jdoe | *0AAD744979343D58A7F17A50E514E6AD6533D04B | +----------+-------------------------------------------+ 1 row in set (0.03 sec)
Although it may look like it is encrypted, a hash is in fact not an encrypted bit of information. Instead, it is a "fingerprint" of the original information. Hashes are generally used, like fingerprints, to perform matches. In this case, when you check your user's password, you will be checking that the hash of the input matches the stored hash. Using hashes alleviates the needand security riskof storing actual passwords.
Creating the Login Form and Script
After you authorize users in your table, you need to give them a mechanism for proving their authenticity. In this case, a simple two-field form will do, as shown in Listing 25.6.
Listing 25.6. User Login Form
Put these lines into a text file called loginform.html, and place this file in your web server document root. Next, you'll create the script itself, which the form expects to be called userlogin.php (see Listing 25.7).
Listing 25.7. User Login Script
Put these lines into a text file called userlogin.php, and place this file in your web server document root. In a moment, you'll try it out, but first let's examine what the script is doing.
Line 3 checks for the two required fieldsthe only two fields in the form: $_POST["username"] and $_POST["password"]. If either of these fields is not present, the script redirects the user back to the original login form. If the two fields are present, the script moves along to line 9, which connects to the database server in preparation for issuing the SQL query to check the authenticity of the user. This query, and its execution, is found in lines 1215. Note that the query checks the hash of the password input from the form against the password stored in the table. These two elements must match each other, and also belong to the username in question, to authorize the user.
Line 18 tests the result of the query by counting the number of rows in the resultset. The row count should be exactly 1 if the username and password pair represents a valid login. If this is the case, the mysqli_fetch_array() function is used in lines 2223 to extract the first and last names of the user. These names are used for aesthetic purposes only.
Line 27 sets the authorization cookie. The name of the cookie is auth, and the value is 1. If a 0 is put in the time slot, the cookie will last as long as this user's web browser session is open. When the user closes the browser, the cookie will expire. Lines 3035 create a message for display, including a link to a file we will create in a moment.
Finally, lines 3640 handle a failed login attempt. In this case, the user is simply redirected back to the original login form.
Go ahead and access the login form, and input the valid values for the John Doe user. When you submit the form, the result should look like Figure 25.1.
Figure 25.1. Successful login result.
Try to log in with an invalid username and password pair, and you should be redirected to the login form. In the next (and final) section, you will create the secretpage.php script, which will read the authentication cookie you have just set and act accordingly.
Testing for the auth Cookie
The last piece of this puzzle is to use the value of the auth cookie to allow a user to access a private file. In this case, the file in question is shown in Listing 25.8.
Listing 25.8. Checking for auth Cookie
From the menu shown in Figure 25.1, click the secret page link. Because you are an authorized user, you should see a result like Figure 25.2.
Figure 25.2. Accessing the secret page as an authorized user.
Close your browser and attempt to access secretpage.php directly. You will find that you cannot, and you will be redirected to the original login form because the authentication cookie has not been set.