June 5, 2011, 7:14 p.m.
posted by lovehurts
Password-Protecting Ajax Requests
Password-protecting Ajax requests is fairly simple because we could simply append an additional variable to the query string that represents a password and verify it on the server side. This would work fine, but could easily be discovered if the password never changedwe would run into the same problem of people being able to see the variable being passed via the request. This is where unique passwords would be extremely helpful because it would be nearly impossible for a hacker to decipher a password and send a malicious request if every request had a unique password.
Creating Unique Passwords
Now that we understand how useful unique passwords will be to our applications' XHRs, we will learn how to create a server-side method that creates them. Let's start by creating the PHP class on the server side called PasswordManager. This object will be a Singleton object so that it is accessible on an applicationwide level. In order to make this object a Singleton, we need to make the constructor function private and create a public static method called getInstance. This method will check to see whether the object has already been instantiated. If not, it will create an instance and return it; if it does exist, the method will return the previously instantiated version of the object. Listing 23.2 shows how this object uses the Singleton design pattern.
Listing 23.2. Creating a Singleton PasswordManager Object
Now that we can access this object applicationwide, we will create a method that will provide us with unique passwords. This method will be called getPassword and will accept an array of unique values that we will define shortly. When the method is called, it takes the array, gets a count for the length of the array that was passed to it, and sets it to a local variable called max. This variable is then used to generate a random number between 0 and itself, which is then set to a local variable called index. The index variable is then used to generate a variable called seed by setting it to this specific index in the array. At this point, we have selected a random value from the array that was passed in as the parameter, which makes it that much harder for a hacker to get the first value correctbut this definitely is not enough yet. To make it even more secure, we take the newly generated seed variable and encrypt it with the md5 encryption method in PHP. md5 is a one-way encryption method, meaning that it cannot be reverse engineered to provide the original seed value that we provided it. After we encrypt the seed, we append a colon and the random index in the array. After we have our password created, we return it to the caller. You may be wondering why we appended the random index to the end of the password; we will cover this when we verify the password during XHRs. See Listing 23.3 for an example of the getPassword method.
Listing 23.3. Creating a Password Array (Constants.class.php)
The array we will use to eventually pass as a parameter to the getPassword method will be added to our Constants object. This array will be another static property so that we can access it applicationwide. The property is named PASSWORD and can include as many values as you want to add to it. This is because when we created the getPassword method, we got the count of the array, so the code is flexible enough to accept any size array. The values in the array can also be any value you want and should be something that is secure, such as a typical password. The values and the number of them can also change as often as you like to make it that much more secure. Listing 23.4 shows this property with a few dummy values as an example.
Creating a Password Array (Constants.class.php)
In order to send the password to the server-side with all of our XHRs, we will add a property to the AjaxUpdater that sends the password each time a request is made. This ensures that all our requests are secure and that we or another developer on our team did not forget to add the password to a request string. It also keeps the code much cleaner so that we do not have random password-protected requests throughout our application. This would make it very difficult to make later updates to the request and would become very unruly. Take a look at Listing 23.5 to get an idea of how this property is added to the AjaxUpdater initialize and Update methods.
Listing 23.5. Adding the Password to All Ajax Requests (AjaxUpdater.js)
Listing 23.6. Setting the Password (mail.php)
We now have a unique password that is being sent with each and every request through the AjaxUpdater, but this doesn't do us any good if we do not verify the password on the server side when the request is made. Let's take a look at how we accomplish this verification and ensure that our requests are secure.