Registration / Login - Implementation in the KKK ================================================ This guide will give its reader an in-depth look at how KittoKittoKitto implements its registration/authentication system. Special attention will be paid to how the user's password is stored and communicated from the client to the server. For more background on the architecture of Kitto, see the [developer guide](http://modulargaming.com/projects/modulargaming/wiki/MgDevelop) maintained by the ModularGaming project. Database Schema --------------- The first thing we will need is a database table to hold our user in. The following _user_ table will be used for the remainder of this guide. It is the Kitto _user_ table with all fields unrelated to this tutorial removed. CREATE TABLE `user` ( -- User & password. `user_id` int(11) NOT NULL auto_increment, `user_name` varchar(25) NOT NULL, `password_hash` char(32) default NULL, `password_hash_salt` char(32) NOT NULL, -- Used for managing logins `current_salt` char(32) NOT NULL, `current_salt_expiration` datetime NOT NULL, -- Profile information `datetime_created` datetime default NULL, `email` text NOT NULL, `age` smallint(3) unsigned NOT NULL, `gender` enum('male','female') NOT NULL, `profile` text NOT NULL, `signature` text NOT NULL, -- Other useful information. `registered_ip_addr` varchar(16) default NULL, `last_ip_addr` varchar(16) default NULL, `last_activity` datetime default NULL, -- Password reset stuff. `password_reset_requested` datetime NOT NULL, `password_reset_confirm` varchar(32) NOT NULL, PRIMARY KEY (`user_id`), UNIQUE KEY `user_name` (`user_name`) ); Registration - Frontend ------------------------ We will need a way to get new users in to the _user_ table. This is achieved via the registration process. Our register page has several components: an HTML form that users fill out, bits of Javascript that assist the user in filling the form out correctly, a PHP script that validates the form, and more PHP that stores the user data in the database. We will begin with a look at [our HTML form](http://github.com/OwlManAtt/kittokittokitto/raw/fe93a820c16e52e9b23147e1a4edca3fae10a7d2/template/templates/user/register_form.tpl). The first line of interest is the form tag - it tells the user's browser where to send the form data (action) and using what HTTP method (method).
The variables in the 'action' attribute form a URL. Kitto makes the base URL (example, http://my-pet-game.com) available as '$display_settings.public_dir'. 'self.slug' is the "file" for the current page - in this case, the action attribute would end up set to _http://my-pet-game.com/register_. We have two choices for our method attribute - GET and POST. As per the HTTP standard, POST is supposed to be used when it causes something to change inside of your application. GET is supposed to be used for retrieving files; GET requests should not cause your application to change. Since registration will result in a new _user_ row being created, POST is the correct method for us to use. We have this hidden form variable next: Since we are submitting the form back to the same URL that the user accesses the form at (http://my-pet-game.com/register), this _state_ variable will tell the PHP script that it's time to process the registration instead of showing the user a form. We'll see this in action later. The rest of the form is contained inside of a table. Each row has a field label, and then a field. Here is the general structure of one of the rows: You must pick a username. The label tag's _for_ attribute matches the _id_ attribute on its form field. The user's browser can use this; most browsers will put your keyboard cursor in the form field if you click on the label. The _id_ attribute on the second table cell (username_td) is needed by the Javascript form validation. Kitto uses a library called Spry for this - it will highlight your form fields in red if the user has done something invalid. It will also show an error message - the _span_ tag around the text "You must pick a username" will be hidden unless the user forgets to fill the field in. We have several more fields. Some considerations: * The password field is present twice. Having the user enter their desired password twice ensures that they have not mis-typed it the first time and are locked out of their account before they even finish signing up. * The email field is only present once. Kitto does not send an activation email to the user. An activation email is used to ensure that the user has entered a valid address; I have not ever cared if the email address provided is valid. It is only used for password recovery. If a user decides that this functionality is not worth the risk of having their email address sold to spam lists, so be it. **If** you would like to send a validation email, you would want to ask for the address to be entered twice to ensure they have not typo'd it and locked themselves out. * The CAPTCHA code field. There is an image with a code displayed instead of a label. The purpose of the CAPTCHA image is to prevent automated scripts from creating users - in theory, only a real human being will be able to determine the correct code from the image. This style of CAPTCHA is *not* completely bullet-proof, but it does significantly deter spam bots. The image is included in our form with a bit of Javascript. The _a_ tag around the image creates a link. If you click on the link, a new image will be loaded (and some things updated on the back-end). The random number at the end of the URL is to prevent a browser from caching the image - it looks like a new URL to the browser, so the image will not be sought in the browser cache. CAPTCHA image Let us take a moment to look at [the source code for the CAPTCHA generator](http://github.com/OwlManAtt/kittokittokitto/raw/fe93a820c16e52e9b23147e1a4edca3fae10a7d2/captcha.php). This script does two things: 1. It comes up with a code and stores the code in a session variable. Sessions are tied to a user's browser by a cookie with a session ID. The actual data in the session is stored on the server. 2. It puts the code in to an image, along with some other random lines/colours. Later on, when are are validating the registration form, we can look at the data in this user's session and make sure that the code they typed in matches the code that the script generated. Switching back to our form HTML - at the very bottom, we have a block of Javascript. There are a number of _Spry.Widget.ValidationSomethingOrOther()_ lines, each defining the rules for valid/invalid data in the form field. We also define a Javascript function to check the two password form fields and ensure that what the user entered in each matches. Registration - Backend ---------------------- When the user has submitted the form, [this PHP script](http://github.com/OwlManAtt/kittokittokitto/raw/fe93a820c16e52e9b23147e1a4edca3fae10a7d2/scripts/user/register.php) validates it, and if the data is all OK, creates the user.