Intranet Journal   Earthweb  
Events Jobs Premium Services Media Kit Network Map E-mail Offers Vendor Solutions Webcasts

   Intranet Journal Subjects
Search Earthweb

Privacy Policy



internet.com
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

internet commerce
Be a Commerce Partner
















 

[ Home | Discussion Forum | How Do I... | Lotus Notes Intranets | Microsoft SharePoint | Products | Shopping  ]

free news!


Creating a PHP-Based Content Management System, Part 5


Peter Zeidman
11/8/2004

Go to page: 1 2 

Printer Friendly Version

Have a question about this article, object-oriented programming, or PHP? Visit Intranet Journal's Discussion Forum

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.

 Note: An updated copy of DbConnector.php, created earlier in the series, is required and is included with this article. There are two changes: blank lines after the closing ?> have been removed, and new functions have been created for extracting the last query used (helpful for debugging), and for returning the number of results found by a query (thanks to forum member w0lf for suggesting that).

Let us now consider what we want our system to do:

  •  Store users' details in the database
  •  Group users into categories, for instance administrators, editors, and staff, in order of security access
  •  Only allow groups of users access to specific areas of the site

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.

 Table: Groups
Column Purpose
   
ID ID of the group
groupname Name of the group

 

 Table: Users
Column Purpose
   
ID ID of the user
user A unique username for the user
pass The user's password, encrypted
thegroup Group to which the user belongs
firstname The user's first name
surname The user's surname
enabled A 1 or a 0 specifies whether the
user is enabled, allowing you to
block troublesome ones

SQL queries for creating the above two tables are below, which can be run in any SQL client:

# Create groups table

CREATE TABLE `cmsgroups` (
`ID` int(4) unsigned NOT NULL auto_increment,
`groupname` varchar(15) default NULL,
PRIMARY KEY (`ID`)
) TYPE=MyISAM;

# Create 10 groups, where 1 has the highest security

INSERT INTO `cmsgroups` VALUES (1,'Admin');
INSERT INTO `cmsgroups` VALUES (2,'Editors');
INSERT INTO `cmsgroups` VALUES (3,NULL);
INSERT INTO `cmsgroups` VALUES (4,NULL);
INSERT INTO `cmsgroups` VALUES (5,NULL);
INSERT INTO `cmsgroups` VALUES (6,NULL);
INSERT INTO `cmsgroups` VALUES (7,NULL);
INSERT INTO `cmsgroups` VALUES (8,NULL);
INSERT INTO `cmsgroups` VALUES (9,NULL);
INSERT INTO `cmsgroups` VALUES (10,'Anonymous');

# Create user table

CREATE TABLE `cmsusers` (
`ID` int(4) unsigned NOT NULL auto_increment,
`user` varchar(20) default NULL,
`pass` varchar(20) default NULL,
`thegroup` int(4) default '10',
`firstname` varchar(20) default NULL,
`surname` varchar(20) default NULL,
`enabled` int(1) default '1',
PRIMARY KEY (`ID`)
) TYPE=MyISAM;

# 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();
header("Cache-control: private");

}

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);
session_destroy
();
exit();

}

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
if (
$_SESSION['user'] && $_SESSION['pass']){

// Validate session data
...

// Look up the user in the database by performing and SQL query
$getUser = $loginConnector->query("SELECT * FROM cmsusers WHERE user = '".$_SESSION['user']."' AND pass = '".$_SESSION['pass']."' AND thegroup <= ".$group.' AND enabled = 1');

// 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");
$this->userdata = $loginConnector->fetchArray($getUser);

if ($loginConnector->getNumRows($getUser) > 0){

// Login OK, store session details

$_SESSION["user"] = $user;
$_SESSION["pass"] = $rowUser["pass"];
$_SESSION["group"] = $rowUser["thegroup"];

// Redirect if goodRedirect was provided

...

} else {

// Login BAD, Destroy session data
unset($this->userdata);

// Redirect to badRedirect if appropriate
return false;

}

}

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

Printer Friendly Version

Of Interest
Intranet Discussion Forum
Creating a PHP-Based Content Management System, Part 1
Creating a PHP-Based Content Management System, Part 2
Creating a PHP-Based Content Management System, Part 3
Creating a PHP-Based Content Management System, Part 4
PHPBuilder

email this page

Tutorials
and more at:
Intranet Journal's Tutorials
Intranet Journal Favorites

Creating a PHP-Based Content Management System

The Spyware Guide

Introduction to Microsoft SharePoint Portal

Intranet Journal
Part of the EarthWeb Network

Managing Editor
Intranet Journal

Tom Dunlap

EarthWeb Home Page
Jupitermedia Home Page

Media Kit




The Network for Technology Professionals

Search:

About Internet.com

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | E-mail Offers