Tải bản đầy đủ (.pdf) (10 trang)

Tương tác giữa PHP và jQuery - part 22 docx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (711.77 KB, 10 trang )

CHAPTER 6 ■ PASSWORD PROTECTION SENSITIVE ACTIONS AND AREAS

211
$obj = new Admin($dbo);

// Load a hash of the word test and output it
$hash1 = $obj->testSaltedHash("test");
echo "Hash 1 without a salt:<br />", $hash1, "<br /><br />";

// Pause execution for a second to get a different timestamp
sleep(1);

// Load a second hash of the word test
$hash2 = $obj->testSaltedHash("test");
echo "Hash 2 without a salt:<br />", $hash2, "<br /><br />";

// Pause execution for a second to get a different timestamp
sleep(1);

// Rehash the word test with the existing salt
$hash3 = $obj->testSaltedHash("test", $hash2);
echo "Hash 3 with the salt from hash 2:<br />", $hash3;

?>
■ Note The sleep() function delays execution of a script by a given number of seconds, passed as its sole
argument. You can learn more about this function at
Your results will not be identical because the timestamp hashes used for the salt will differ; however,
your results should look something like this:
Hash 1 without a salt:
518fd85bb85815af85e88b7c43d892238af9a5ca5775807


Hash 2 without a salt:
93b14e3f42ca09cafc1330b592669a5d02e9815bc2f69de

Hash 3 with the salt from hash 2:
93b14e3f42ca09cafc1330b592669a5d02e9815bc2f69de
CHAPTER 6 ■ PASSWORD PROTECTION SENSITIVE ACTIONS AND AREAS

212
As you can see, hashes of the word test don’t match up when passed separately; however, if you
supply an existing salted hash of test, the same hash is produced. This way, even if two users have the
same password, their stored hashes will be different, making it much more difficult for potential
attackers to crack passwords.
■ Note Bear in mind that no algorithm is 100% effective. However, using techniques like salted hashes makes it
possible to reduce the possibility of an attack significantly.
Creating a User to Test Administrative Access
In order to test the administrative functions, you’ll need a username/password pair to exist in your users
table. For simplicity, the username will be testuser, the password will be admin, and the email address
will be Keep in mind that this is not a secure password; it is being used for illustration
purposes only, and it should be changed before you use it with any production scripts.
Begin by generating a hash of the password, admin, which is easy using the test method
testSaltedHash() and test.php. Add the following bold code to test.php to generate a salted hash of
your test user’s password:

<?php

// Include necessary files
include_once ' /sys/core/init.inc.php';

// Load the admin object
$obj = new Admin($dbo);


// Generate a salted hash of "admin"
$pass = $obj->testSaltedHash("admin");
echo 'Hash of "admin":<br />', $pass, "<br /><br />";

?>

Navigate to http://localhost/test.php, and you’ll see output similar to the following:
Hash of "admin":
a1645e41f29c45c46539192fe29627751e1838f7311eeb4
Copy the hash, navigate to http://localhost/phpmyadmin, and then click the SQL tab. Execute the
following query to insert a test user into the table:

INSERT INTO `php-jquery_example`.`users`
(`user_name`, `user_pass`, `user_email`)
VALUES
CHAPTER 6 ■ PASSWORD PROTECTION SENSITIVE ACTIONS AND AREAS

213
(
'testuser',
'a1645e41f29c45c46539192fe29627751e1838f7311eeb4',
''
);


After executing the preceding code, click the php-jquery_example database, and then the users table.
Select the Browse tab to view the user info in the table (see Figure 6-3).

Figure 6-3. The test user data after inserting it into the database

Now that a user exists in the user database with a salted hash stored, you can delete both the
testSaltedHash() method from the Admin class and the entire test.php file.
Modifying the App to Handle the Login Form Submission
At this point, you’re almost ready to test a user login. Before it will work, however, you need to modify
process.inc.php to handle form submissions from the login form.
Due to the way the file is set up, this change is as simple as adding a new element to the $actions
array. Open process.inc.php and insert the following bold code:

<?php

/*
CHAPTER 6 ■ PASSWORD PROTECTION SENSITIVE ACTIONS AND AREAS

214
* Enable sessions
*/
session_start();

/*
* Include necessary files
*/
include_once ' / / /sys/config/db-cred.inc.php';

/*
* Define constants for config info
*/
foreach ( $C as $name => $val )
{
define($name, $val);
}


/*
* Create a lookup array for form actions
*/
$actions = array(
'event_edit' => array(
'object' => 'Calendar',
'method' => 'processForm',
'header' => 'Location: / /'
),
'user_login' => array(
'object' => 'Admin',
'method' => 'processLoginForm',
'header' => 'Location: / /'
)
);

/*
* Make sure the anti-CSRF token was passed and that the
* requested action exists in the lookup array
*/
if ( $_POST['token']==$_SESSION['token']
&& isset($actions[$_POST['action']]) )
{
$use_array = $actions[$_POST['action']];
$obj = new $use_array['object']($dbo);
if ( TRUE === $msg=$obj->$use_array['method']() )
{
header($use_array['header']);
exit;

}
else
{
// If an error occured, output it and end execution
die ( $msg );
CHAPTER 6 ■ PASSWORD PROTECTION SENSITIVE ACTIONS AND AREAS

215
}
}
else
{
// Redirect to the main index if the token/action is invalid
header("Location: / /");
exit;
}

function __autoload($class_name)
{
$filename = ' / / /sys/class/class.'
. strtolower($class_name) . '.inc.php';
if ( file_exists($filename) )
{
include_once $filename;
}
}

?>

Now you can officially test a login. Because no checks for a login are in place yet, simply add a

conditional comment in index.php to show login or logout status by inserting the following bold line into
the file:

<?php

/*
* Include necessary files
*/
include_once ' /sys/core/init.inc.php';

/*
* Load the calendar
*/
$cal = new Calendar($dbo, "2010-01-01 12:00:00");

/*
* Set up the page title and CSS files
*/
$page_title = "Events Calendar";
$css_files = array('style.css', 'admin.css');

/*
* Include the header
*/
include_once 'assets/common/header.inc.php';

?>

<div id="content">
CHAPTER 6 ■ PASSWORD PROTECTION SENSITIVE ACTIONS AND AREAS


216
<?php

/*
* Display the calendar HTML
*/
echo $cal->buildCalendar();

?>

</div><! end #content >
<p>
<?php

echo isset($_SESSION['user']) ? "Logged In!" : "Logged Out!";

?>
</p>

<?php

/*
* Include the footer
*/
include_once 'assets/common/footer.inc.php';

?>

Now save this file and navigate to http://localhost/ to see the “Logged Out!” message below the

calendar (see Figure 6-4).
CHAPTER 6 ■ PASSWORD PROTECTION SENSITIVE ACTIONS AND AREAS

217

Figure 6-4. Before the user logs in, the “Logged Out!” message appears below the calendar
Next, navigate to http://localhost/login.php and enter the username testuser with the password,
admin (see Figure 6-5).


Figure 6-5. The login form with the username and password information entered
CHAPTER 6 ■ PASSWORD PROTECTION SENSITIVE ACTIONS AND AREAS

218
After clicking the Log In button, you’ll be redirected back to the calendar; however, now the
message below the calendar will read “Logged In!” (see Figure 6-6).


Figure 6-6. After the user logs in, the “Logged In!” message appears below the calendar
Allowing the User to Log Out
Next, you need to add a method that allows the user to log out. You will do this using a form that submits
information to process.inc.php. The method _adminGeneralOptions() in the Calendar class generates
the form.
Adding a Log Out Button to the Calendar
To add a button that allows users to log out, modify _adminGeneralOptions() in the Calendar class. In
addition to providing a button for adding new events, this method will now also output a form that
submits the site token and an action value of user_logout to process.inc.php. Open the Calendar class
and modify _adminGeneralOptions() with the following bold code:

private function _adminGeneralOptions()

{
/*
* Display admin controls
CHAPTER 6 ■ PASSWORD PROTECTION SENSITIVE ACTIONS AND AREAS

219
*/
return <<<ADMIN_OPTIONS

<a href="admin.php" class="admin">+ Add a New Event</a>
<form action="assets/inc/process.inc.php" method="post">
<div>
<input type="submit" value="Log Out" class="admin" />
<input type="hidden" name="token"
value="$_SESSION[token]" />
<input type="hidden" name="action"
value="user_logout" />
</div>
</form>
ADMIN_OPTIONS;
}

Now save the changes and refresh http://localhost/ in your browser to see the new button (see
Figure 6-7).


Figure 6-7. The Log Out button as it appears after you modify the Calendar class
CHAPTER 6 ■ PASSWORD PROTECTION SENSITIVE ACTIONS AND AREAS

220

Creating a Method to Process the Logout
To process the logout, a new public method called processLogout() needs to be added to the Admin class.
This method does a quick check to make sure the proper action, user_logout, was supplied, and then
uses session_destroy() to remove the user data array by destroying the current session entirely.
You add this method to the Admin class by inserting the following bold code:

<?php

class Admin extends DB_Connect
{

private $_saltLength = 7;

public function __construct($db=NULL, $saltLength=NULL) { }

public function processLoginForm() { }

/**
* Logs out the user
*
* @return mixed TRUE on success or messsage on failure
*/
public function processLogout()
{
/*
* Fails if the proper action was not submitted
*/
if ( $_POST['action']!='user_logout' )
{
return "Invalid action supplied for processLogout.";

}

/*
* Removes the user array from the current session
*/
session_destroy();
return TRUE;
}

private function _getSaltedHash($string, $salt=NULL) { }

}

?>

×