|
|
|
|
|
|
Creating a PHP-Based Content Management System, Part 5
Welcome to the
penultimate installment of the series. So far we've looked at the basics
of database interaction using PHP, as well as some vital techniques such
as validation and error handling. We've allowed anyone to be able to add
or remove content at the touch of a button, without programming knowledge.
However, we've been rather to liberal in allowing 'anyone' to make changes.
We need to keep certain areas of the site, such as the admin system, private.
Sadly, few people will respect a "keep out" sign, and this month
we'll be creating a class that'll act as a guard for the more private areas
of your Intranet. I should emphasize
that this is a very basic type of security, and techniques such as secure
servers, secure data transmission and encryption are not covered by this
article. These should be investigated if you're planning on storing any sensitive
information. Let us now consider
what we want our system to do: The first bit
we'll need to secure is the admin area, used for adding and removing content
on the site. To get started, we'll set up database tables to store our user
information. SQL queries for
creating the above two tables are below, which can be run in any SQL client: # Create groups table CREATE TABLE `cmsgroups` ( # Create 10 groups, where 1 has the highest security INSERT INTO `cmsgroups` VALUES (1,'Admin'); # Create user table CREATE TABLE `cmsusers` ( # Create sample user INSERT INTO `cmsusers` VALUES (1,'admin',PASSWORD('admin'),1,'Mr','Admin',1); So how should
we go about securing our site? We're going to write a class called Sentry
to check whether a user is logged in. The system we're going to rely on is
called sessions, a method of storing a user's details for the duration
of their visit to the website or Intranet. The constructor
function (the function executed when the class is created) is as follows: function sentry(){ session_start(); } This simply tells
PHP to start the session, and adds a header that stops the password being
stored in the user's cache. The function to logout is equally simple: function logout(){ unset($this->userdata); } This destroys
the variable containing the user's details, the session data, and prevents
further code from being executed. We next create a function to check whether
the
user
is already
logged in,
and
optionally
to actually perform a login. The function has a number of parameters: function checkLogin($user
= '',$pass = '',$group = 10,$goodRedirect = '',$badRedirect = ''){ We pass the username
and password checkLogin, and if either of these are incorrect then the page
should redirect to the address stored in $badRedirect. If $user and $pass
are correct, we redirect to $goodRedirect. $group is used to specify the
minimum group level that's allowed to access this resource, we'll specify
that group level 10 has the least security privileges, group 1 has the most.
If checkLogin finds that the user is already logged in, it should confirm
that the original username and password provided are still valid. Our first clause
in checkLogin takes a look at whether a user seems to be logged in, by checking
whether the session variables already exist: // User is already logged in, check credentials // Validate session data // Look up the user in the database
by performing and SQL query // Redirect to goodRedirect or badRedirect appropriately Notice in the
above code, we use the PASSWORD function in the SQL query. For those of you
not familiar with this, here's how it works. When we originally create the
user's record in the database, we don't store the plain password; instead
we use the PASSWORD function to encrypt it. What is now stored in the database
is an apparently random string of letters and numbers, and the original password
can never be recovered (hopefully). When we then come to check a login, we
perform the same jumbling function on the provided password, and compare
the result with the string of letters stored previously. If they're the same,
then the original passwords match, and the user is authenticated. The next piece
of code is used when a user hasn't previously logged in: }else{ // Validate the input ... // Lookup the user in the DB $getUser = $loginConnector->query("SELECT
* FROM cmsusers WHERE user = '$user' AND pass = PASSWORD('$pass') AND thegroup <=
$group AND enabled = 1"); if ($loginConnector->getNumRows($getUser) > 0){ // Login OK, store session
details } else { // Login BAD, Destroy session data // Redirect to badRedirect if appropriate } } If more than one
result is found in the database, i.e. the user's details were correct, the
username, password and group are stored in the session. OK, We're pretty
much done. Let's now test our class by creating a login form and a test page
we want to restrict.
Go to page: 1 2
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Intranet Journal's Tutorials |
|
Managing Editor |