Please wait...
Popular Resources
Recent Forum Posts

Secure Sessions Class

Posted: 18-11-11 09:46     

When creating websites with multiple pages, sometimes it is a good idea to be passing information from page to page based on the current user. PHP holds a way of doing this called sessions. Sessions allow variables to be used across multiple pages while been set, modified and created. However, PHP sessions are not the most secure form of doing this.

In this tutorial we will look at a custom way of passing details from page to page without PHP sessions. To do this we will use cookies and a MySQL database. There will be hints throughout the tutorial on making classes/variables and functions or you can read the The full script is available at the end of this tutorial.

First, make a PHP file called “class.session.php”. This will contain all of the back end code for our class.

Start your class with a name of sessionsClass.

Code
1
2
3
4
5
6
7
8
 
<?php 
class sessionsClass
{
 
} 
?>
 
 

We have our class, we now need some variables. Add a variable called “cookieName”, one called “sessionHash”, one called “expireTime” and one called “sessionData”.

Code
1
2
3
4
5
6
7
8
9
 
var $cookieName;
 
var $sessionHash;
 
var $expireTime;
 
var $sessionData;
 
 

These variables will be used later on by our class. Now we need a function. This function will be the one that starts our session and handles new pages. Give it a name “_sessionStart”. You should now have something like below:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
<?php
 
class sessesionClass
{
 
      var $cookieName;
 
      var $sessionHash;
 
      var $expireTime;
 
      var $sessionData;
 
      public function _sessionStart()
      {
 
      }
 
}
 
?>
 
 

In our starting function we need to set our variables. Our cookieName can be whatever you like, something unique like “my_session_cookie”. Our sessionHash variable is either going to be the value of our cookie (if one exists) or blank to start with. But if we have a blank sessionHash, how are we going to track a user?

Well we need to make the cookie then. So add the following code to your starting function.

Code
1
2
3
4
5
6
7
8
9
10
 
$this->cookieName = "my_session_cookie";
$this->expireTIme = "3600";
 
if( isset( $_COOKIES[ $this->cookieName ] ) )
{
      # Our cookie exists and has a value.
      $this->sessionHash = $_COOKIES[ $this->cookieName ];
}
 
 

We have done a lot above so let’s break it down. First we have set the name of our cookie. I have used a name “my_session_cookie”. Next we have checked if the cookie exists on the users machine. If it does, we have set our sessionHash variable to the value of the cookie. This is how we will track this user through our pages. We have also set our expireTime variable. This is used to set how long a user can stay inactive on a page before the session becomes invalid in seconds. We have set it to 15 minutes.

Now, if the cookie doesn’t exist, we have to create it. For this we need a new function. Create a function called createCookie.

Code
1
2
3
4
5
6
7
8
9
10
 
public function createCookie()
{
      $hash = md5( time() . uniqid() );
 
      setcookie( $this->cookiename, $hash, time()+$this->expireTime );
 
      $this->sessionHash = $hash;
}
 
 

What have we done here? First we have made a variable called hash. This hash contains a unique set of characters we will use to identify the user. We make this by taking the current timestamp using the function time() and the function uniqid() which generates a unique number. Finally we encrypt it using the md5() function which produces a 32-bit encrypted string which will be unique to this user.

Secondly we are creating a cookie on the users machine using the function setcookie(). The first parameter is our cookieName (the name of the cookie). Second is the hash string we made and finally we have set the expiry time to the current time which is time() plus 9999999 seconds so it won’t expire until we delete it.

Finally we have set our sessionHash variable in our class to the hash string we just made.

Now go back to the start function. We need to add some code to make the cookie if it doesn’t exist. At the end of the current code add:

Code
1
2
3
4
5
6
 
else
{
      createCookie();
}
 
 

The code above simply calls our createCookie() function if the cookie doesn’t exist. So you should have.

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
$this->cookieName = "my_session_cookie";
$this->expireTIme = "3600";
 
if( isset( $_COOKIES[ $this->cookieName ] ) )
{
      # Our cookie exists and has a value.
      $this->sessionHash = $_COOKIES[ $this->cookieName ];
}
else
{
      createCookie();
}
 
 

Up to now, we have checked if a cookie exists and if not create one. So we can track our user through our pages now.

Now we get to the database side of our session management. In your database create a table called sessions with the following columns:

  1. sessionHash – varchar – length:32
  2. sessionIP – varchar – length:30
  3. sessionTime – int – length:11
  4. sessionPage – varchar – length:100
  5. sessionData – text
  6. sessionExpire – int – length:11

We no have our database table to store and check sessions from. From here we can do some session checking. Create a function called sessionCheck. Within this session we are going to query our database to find a match for our sessionHash within our cookie while checking the IP address and expiry time.

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
public function sessionCheck()
{
      $hash = mysql_real_escape_string( $this->sessionHash );
      $ip = $_SERVER['REMOTE_ADDR'];
      $expiryLimit = time() - $this->expireTime;
 
      $check = mysql_query( "SELECT * FROM sessions WHERE sessionHash = '{$hash}'
                            AND sessionIP = '{$ip}'" );
 
      if( mysql_num_rows( $check ) > 0 )
      {
            # Session exists and is valid.
            return true;
      }
      else
      {
            # Session does not exist or is invalid.
            return false;
      }
}
 
 

Right, lets run through our function. We have started by setting our hash which we get from our class. However we are passing it through a function called mysql_real_escape_string(). This takes away any malicious code that could be contained in the value of the cookie and prevents from SQL Injection. Next we have set the IP which we have gotten from PHP’s $_SERVER global variable. We have also set a variable called expiryLimit. This value is set to the current time using time() minus the expireTime in our class to give us the time cut-off for expired sessions.

Now we these variables we can search for a valid session in the database. We perform a select where our hash string matches, the IP matches and where the sessionTime is after the expiryLimit. If all these conditions are met, we have a valid session and can start getting the session data. If they are not all matches we return false because the session does not exist.

There are a few things we need to add to this function. We need to update the session so it doesn’t expire and we also need our session data. So go to your function where the line reads “return true;” and replace it with:

Code
1
2
3
4
5
6
7
8
9
10
11
 
$sessionInfo = mysql_fetch_array( $check );
 
$this->sessionData = unserialize( $sessionInfo['sessionData'] );
 
$expire = time() + $this->expireTime;
 
$update = mysql_query( "UPDATE sessions SET sessionExpire = '{$expire}' WHERE sessionHash = '{$hash}'" );
 
return true;
 
 

This may look complicated. First we have got the rows from the check of our session and now have an array of the column data. Then we are returning some data. The data we are setting our sessionData (our variable we made in our class). First we are using a function called unserialize(). This decodes data, and we will go into this in detail further in the tutorial. Then we are calling the sessionData from our array.

Next we have made a variable called expire and set its value to the current time plus our expire time. Then we run an update query on our sessions table to set the new expire time for the current sessionHash.

Now at this point our class variable called sessionData holds all the session data for the current user and our session stays updated on each page refresh.

Your code should now look like this:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 
 
class sessesionClass
{
 
      var $cookieName;
 
      var $sessionHash;
 
      var $expireTime;
 
      var $sessionData;
 
      public function _sessionStart()
      {
            $this->cookieName = "my_session_cookie";
            $this->expireTIme = "3600";
 
            if( isset( $_COOKIES[ $this->cookieName ] ) )
            {
                   # Our cookie exists and has a value.
                   $this->sessionHash = $_COOKIES[ $this->cookieName ];
            }
            else
            {
                   createCookie();
            }
      }
 
      public function createCookie()
      {
            $hash = md5( time() . uniqid() );
 
            setcookie( $this->cookiename, $hash, time()+$this->expireTime );
 
            $this->sessionHash = $hash;
      }
 
      public function sessionCheck()
      {
            $hash = mysql_real_escape_string( $this->sessionHash );
            $ip = $_SERVER['REMOTE_ADDR'];
            $expiryLimit = time() - $this->expireTime;
 
            $check = mysql_query( "SELECT * FROM sessions WHERE sessionHash = '{$hash}'
                            AND sessionIP = '{$ip}'" );
 
            if( mysql_num_rows( $check ) > 0 )
            {
                  # Session exists and is valid.
                  $sessionInfo = mysql_fetch_array( $check );
 
                  $this->sessionData = unserialize( $sessionInfo['sessionData'] );
 
                  $expire = time() + $this->expireTime;
 
                  $update = mysql_query( "UPDATE sessions SET sessionExpire = '{$expire}' WHERE sessionHash = '{$hash}'" );
 
                  return true;
            }
            else
            {
                  # Session does not exist or is invalid.
                  return false;
            }
      }
 
}
 
 

Hopefully your code looks like the above so far. Now we only need one more function, and that is to set /change our session data. So create a new function called setSessionData. Within this we will be running a MySQL query to set our data into the database. Here is what we will have.

Code
1
2
3
4
5
6
7
8
9
 
public function setSessionData()
{
      $serialiseData = serialize( $this->sessionData );
 
      mysql_query( "UPDATE sessions SET sessionData = '{$serialiseData}' WHERE sessionHash = '{$this->sessionHash}'" );
 
}
 
 

First of all we have serialized our sessionData. We serialize the data so it can be stored in the database in a safe and efficent way. But each time we return the data we unserialize it so PHP can work with it.

Next we are running a query to update the sessionData for the current sessionHash.

This function would be called normally at the end of the PHP script to save all the data that has been changed through the script. That’s our class created. Lets learn how to use it. Make a new PHP page, with any name, this is just a test.

Within this page we will run through how to use the class properly. First we need to reference our sessions class. We do this by including the class file and then calling a new instance of the class name.

Code
1
2
3
4
5
 
include "class.session.php";
 
$sessions = new sessionClass;
 
 

At the start of your PHP script you will call your _sessionStart function.

Then you will call sessionCheck(). This function will return false if there is a problem with the session or will return true if the session is valid. So an example:

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
<?php
 
include "class.session.php";
 
$sessions = new sessionClass;
 
$sessions->_sessionStart();
 
$sessionInfo = $sessions->sessionCheck();
 
if( $sessionInfo = false )
{
      # This session is invalid. Tell the user.
}
else
{
      # Session is valid, can use the data.
}
 
?>
 
 

Above we have referenced our session class and made it accessible by the $sessions variable. Then we started our session, then we stored the session information in a variable. Last, we checked if the session was valid, if it wasn’t we should tell the user and if it is, we can start using the data.

To use the data returned by the session we can call:

Code
1
2
3
 
$fullName = $sessioninfo['fullname'];
 
 

That is if you have already set that and saved it to the database. Next let’s try and save some data to our session. For this we update the sessionData variable and then use our setSessionData function to save it.

Code
1
2
3
4
5
 
$sessions->sessionData['myNewValue'] = "hello";
 
$sessions->setSessionData();
 
 

That’s it. You can also update values in the exact same way. Remember, if you dont call the setSessionData function, the session information will not be stored in the database.

This sessions class can easily be used to create a login system, by using the function to check if a users session exists or not.

If you’re feeling adventurous, you could now try and create a function to delete any old sessions from the database. I will reveal the solution to this in a few days, but see if you can do it.

Here is a full run down of what your code should look like.
class.session.php

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
 
class sessesionClass
{
 
      var $cookieName;
 
      var $sessionHash;
 
      var $expireTime;
 
      var $sessionData;
 
      public function _sessionStart()
      {
            $this->cookieName = "my_session_cookie";
            $this->expireTIme = "3600";
 
            if( isset( $_COOKIES[ $this->cookieName ] ) )
            {
                   # Our cookie exists and has a value.
                   $this->sessionHash = $_COOKIES[ $this->cookieName ];
            }
            else
            {
                   createCookie();
            }
      }
 
      public function createCookie()
      {
            $hash = md5( time() . uniqid() );
 
            setcookie( $this->cookiename, $hash, time()+$this->expireTime );
 
            $this->sessionHash = $hash;
      }
 
      public function sessionCheck()
      {
            $hash = mysql_real_escape_string( $this->sessionHash );
            $ip = $_SERVER['REMOTE_ADDR'];
            $expiryLimit = time() - $this->expireTime;
 
            $check = mysql_query( "SELECT * FROM sessions WHERE sessionHash = '{$hash}'
                            AND sessionIP = '{$ip}'" );
 
            if( mysql_num_rows( $check ) > 0 )
            {
                  # Session exists and is valid.
                  $sessionInfo = mysql_fetch_array( $check );
 
                  $this->sessionData = unserialize( $sessionInfo['sessionData'] );
 
                  $expire = time() + $this->expireTime;
 
                  $update = mysql_query( "UPDATE sessions SET sessionExpire = '{$expire}' WHERE sessionHash = '{$hash}'" );
 
                  return true;
            }
            else
            {
                  # Session does not exist or is invalid.
                  return false;
            }
      }
 
      public function setSessionData()
      {
             $serialiseData = serialize( $this->sessionData );
 
	     mysql_query( "UPDATE sessions SET sessionData = '{$serialiseData}' WHERE sessionHash = '{$this->sessionHash}'" ); 
      }
 
}
 
 

test.php

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
<?php
 
include "class.session.php";
 
$sessions = new sessionClass;
 
$sessions->_sessionStart();
 
$sessionInfo = $sessions->sessionCheck();
 
if( $sessionInfo = false )
{
      # This session is invalid. Tell the user.
}
else
{
      # Session is valid, can use the data.
      echo "Your name is " . $sessionInfo->sessionData['fullname'];
 
      # Update the name.
      $sessionInfo->sessionData['fullname'] = "My New name";
 
      $sessionInfo->setSessionData();
}
 
?>
 
 

Hopefully this tutorial has been useful and you have learnt about classes and databases along the way.