- {foreach from=$error item=str}
- {$str|escape} {/foreach}
Thank you {$user->profile->first_name|escape}, your registration is now complete
Your password has been e-mailed to you at {$user->profile->email|escape}
{include file='footer.tpl'} Adding CAPTCHA to the User Registration Form Now that we have the core functionality of the user registration system working, we can improve it slightly by adding a simple yet effective security measure to ensure that registrations come only from real people and not computer programs This security measure is called CAPTCHA, which stands for Completely Automated Public Turing test to tell Computers and Humans Apart There are many different types of CAPTCHA tests available, but we will be using what is probably the most common one This is where a series of characters are shown as an image, and the user is required to identify these characters by typing them in as part of the form they are submitting We will be using the Text_CAPTCHA component from PEAR (the PHP Extension and Application Repository) to generate our CAPTCHA images Note that we will be using a CAPTCHA test for several forms in our web application, not just the registration form 9063CH04CMP4 11/20/07 9:20 PM Page 89 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com CHAPTER ■ USER REGISTRATION, LOGIN, AND LOGOUT An example of a CAPTCHA image that Text_CAPTCHA generates is shown in Figure 4-2 The random lines and shapes help to fool optical character recognition (OCR) software that may try to automatically decipher the CAPTCHA Figure 4-2 A sample CAPTCHA image generated by PEAR’s Text_CAPTCHA Circumventing CAPTCHA Although the point of the CAPTCHA test is to tell computers and humans apart, it is technically possible to write a program that can solve a CAPTCHA automatically In the case of the text CAPTCHA we will be using, OCR software could be used to determine the characters in the image Because of this, we try to distort the images to a point where using OCR software is not possible, but not too far so that humans cannot determine which characters are being displayed This means avoiding characters such as zero and the letter O completely, which can easily be confused CAPTCHA and Accessibility Another important consideration when implementing a CAPTCHA test in your web applications is accessibility If somebody is unable to pass the test, they will be unable to complete the form protected by the CAPTCHA test As such, it is important to have alternative methods available One possible solution is to implement an audio CAPTCHA in addition to the text CAPTCHA This would involve generating an audio file that reads back letters, numbers, or words, which the user must then type in 89 9063CH04CMP4 11/20/07 9:20 PM Page 90 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 90 CHAPTER ■ USER REGISTRATION, LOGIN, AND LOGOUT Another alternative is to have a manual registration system, where the user can e-mail their details to the site administrator who can then save their details on their behalf In Chapter 14 we will discuss the implementation of an administration area in our web application Part of this administration area will be a user management section where an administrator could manually create new users PEAR’s Text_CAPTCHA To generate CAPTCHA images, we will be using the Text_CAPTCHA component from PEAR Text_CAPTCHA will generate the series of characters to appear in the image and then create an image with those characters appearing at a random angles in random locations It will also add some random noise to prevent OCR software from reading the letters This noise is a series of lines and shapes that will be placed randomly on the image Before you can use Text_CAPTCHA, you must install it It is available for download from http://pear.php.net/package/Text_CAPTCHA, or you can use the PEAR installer to simplify installation Text_CAPTCHA also relies on the Text_Password and Image_Text components, so you must also install them To install these packages using the PEAR installer, use the following commands: # pear install -f Text_CAPTCHA # pear install -f Image_Text Because neither of these packages have a stable release at time of writing, I used the –f argument, which forces installation of a non-stable version The first command should automatically install Text_Password, but if it doesn’t, use the following command: # pear install Text_Password Text_CAPTCHA also needs a TrueType font available in order to write letters to the CAPTCHA image Any font will for this, as long as its characters are easy to read The font file I use in this book is the bold version of Vera (VeraBD.ttf), available from the Gnome web site (http://www.gnome.org/fonts/) I chose this font because its license terms allow it to be freely distributed The font should be stored in the application data directory (/var/www/ phpweb20/data/VeraBD.ttf) Generating a CAPTCHA Image In order to add CAPTCHA capabilities to our application, we need to create a new controller action that will be responsible for outputting the image The CAPTCHA is not specific to user registration, so we will call this controller utility, as there may be other utility actions we want to add later 9063CH04CMP4 11/20/07 9:20 PM Page 91 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com CHAPTER ■ USER REGISTRATION, LOGIN, AND LOGOUT Listing 4-13 shows the contents of UtilityController.php, which we will store in /include/Controllers Presently there is just one action, which is responsible for generating and outputting the image Listing 4-13 Generating a CAPTCHA Image Using Text_CAPTCHA (UtilityController.php) You can now view the generated CAPTCHA image directly in your browser by visiting http://phpweb20/utility/captcha (This is how I generated Figure 4-2.) Unlike all of the previous controller actions we have implemented so far, which returned HTML code, this action returns image data (along with the corresponding headers so browsers knows how to display the data) Adding the CAPTCHA Image to the Registration Form The next step in integrating the CAPTCHA test is to display the image on the registration form To this, we simply use an HTML tag to show the image, and we add a text input so the user can enter the phrase Listing 4-15 shows the relevant HTML code we need to add to the register.tpl form created earlier in this chapter (located in /templates/account) The convention with CAPTCHA images is to add them at the end of the form, above the submit button Listing 4-15 Displaying the CAPTCHA Image on the Registration Form (register.tpl) {include file='header.tpl'} Create an Account Enter Above Phrase: 93 9063CH04CMP4 11/20/07 9:20 PM Page 94 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 94 CHAPTER ■ USER REGISTRATION, LOGIN, AND LOGOUT {include file='lib/error.tpl' error=$fp->getError('captcha')} {include file='footer.tpl'} One thing to notice in this code is that we still prepopulate the captcha field in this form This is so the user only has to enter it successfully once For example, if they enter an invalid e-mail address but a valid CAPTCHA phrase, they shouldn’t have to enter the CAPTCHA phrase again after fixing their e-mail address Figure 4-3 shows the registration form with the CAPTCHA image and the corresponding text input field Figure 4-3 The registration form with a CAPTCHA image and text input field to receive the phrase from the user 9063CH04CMP4 11/20/07 9:20 PM Page 95 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com CHAPTER ■ USER REGISTRATION, LOGIN, AND LOGOUT Validating the CAPTCHA Phrase Finally, we must check that the submitted CAPTCHA phrase matches the one stored in the session data To this, we need to add a new check to the process() method in FormProcessor_ UserRegistration We also need to clear the saved phrase once the form is completed This is so a new phrase is generated the next time the user tries to anything that requires CAPTCHA authentication Listing 4-16 shows the additions to FormProcessor_UserRegistration that check for a valid phrase and clear out the phrase upon completion Listing 4-16 Validating the Submitted CAPTCHA Phrase (UserRegistration.php) Adding E-mail Functionality The final function we must add to the user registration system is one that sends the newly registered user a confirmation of their account, as well as their randomly generated password so they can log in Sending them their password by e-mail is an easy way to validate their e-mail address 95 9063CH04CMP4 11/20/07 9:20 PM Page 96 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 96 CHAPTER ■ USER REGISTRATION, LOGIN, AND LOGOUT To send e-mail from our application, we will use the Zend_Mail component of the Zend Framework We could instead use the PHP mail() function, but by using a class such as this (or even PEAR’s Mail_Mime), we can a whole lot more, such as attaching files (including images) and sending HTML e-mail We won’t be doing either in this book, but if you ever wanted to add such functionality, the key code would already be in place Listing 4-17 shows a basic example of using Zend_Mail This script sends a single e-mail to the address specified with the call to addTo() You can use this script to ensure that your e-mail server is correctly sending e-mail (remember to update the recipient address to your own) Listing 4-17 Example Usage of Zend_Mail to Send an E-mail (listing-4-17.php) Before we can make our user registration system send out an e-mail, we must first add functionality to DatabaseObject_User for sending e-mail to users—this will allow us to easily send other e-mail messages to users as well (such as instructions for resetting a forgotten password) We will use Smarty for e-mail templates, just as we for outputting the web site HTML Our e-mail templates will be structured so the first line of the template is the e-mail subject, while the rest of the file constitutes the e-mail body Listing 4-18 shows the sendEmail() function, which we will add to the DatabaseObject_ User class It takes the filename of a template as the argument, and feeds it through Smarty before using Zend_Mail to send the resulting e-mail body to the user Listing 4-18 A Helper Function Used to Send E-mail to Users (User.php)