Free Web Hosting

Code Igniter Session Library :: Reloaded

Important Notice: 08 January 2008

I have ported all my own applications to Kohana 2.0 The bundled Session library is advanced and therefore I no longer have any reason to maintain a third party session manager

As of this writing, Codeigniter Session library does not provide the functionality of OBSession. I have switched to Kohana and no longer use CodeIgniter. As a courtesy to anyone who is using OBSession, the library will remain available from this site. The code is stable and bug free as far as I can determine.

If you are using OBSession, and believe you have found a bug, please contact me with information as to how to replicate the bug, and I will post a patch if required. My address is oscar dot bajner at "gee" mail dot com

Quick Updates:

Updates 29 April 2008 Bugfix version 2.0.2

Updates 27 June 2007 Bugfix version 2.0.1

02 June 2007 Quick Clarification
I am no longer participating on the CodeIgniter forums. Please note I will no longer respond to any posts on that forum, public or private.

If you have any queries, please contact me here Kohana forums

Updates 21 May 2007 Version 2 available.

Candy's dandy but Liquor's quicker.

Code Igniter's standard session library has many critics, enough to produce three or more competitors. Whatever the critics say, most have agreed that the library does provide a neat interface to session handling, is simple and intuitive to use and well documented.

Major weaknesses of the library :

  1. Security : The User Data is stored in a cookie, client-side.
  2. Security : The session is vulnerable to session fixation.
  3. Usability : Enabling the session database does not actually store User-Data in the database!
  4. Usability : Things like non-persistent sessions, flash variables and session id regeneration are not enabled.

Some solutions have utilized the PHP native session handler. This works well and is an attractive option.
The original reason Rick wrote the custom library was to avoid unpredictable results with PHP's configuration and setup variances across hosts. A custom library (should) provide the developer with finer control and dependability.

Enter the Dragon.

So, I have had a go at re-working the existing library. I have pandered to my own requirements first, but I think I have managed to include many of the things people have been requesting.

    Featuring >>> For Code Igniter v 1.5.x
  1. Chuck Norris : User-Data can now be stored server side in a Database!
  2. Bruce Lee : (Mostly) fully compatible, drop-in replacement for the existing library.
  3. Jackie Chang : More Configurable, enabling non-persistent sessions, timeouts, flash data and convenience functions.
  4. Derek Allard : How did he get onto the set!?!

My Big Fat Geek Wedding.

The following assumes at least nodding aquaintance with CI session library usage.

The library is a replacement library, called Session.php which you need to place into your /application/libraries directory. When your app loads the session library, CI will automatically load the replacement library, so there is no need to change anything in your existing code. Note, as it is a replacement library, you may simply overwrite the Session.php file in the /system/libraries/ directory.

You will need to make some changes to your application/config/config.php file. Some of the config settings have slight changes in meaning, some have been removed and a few new ones added.

Sample Config file Extract:

$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 0;
$config['sess_encrypt_cookie'] = FALSE;
$config['sess_table_name'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_match_useragent'] = TRUE;
// [OB] additional config items: Set to 'database' to keep userdata exclusively on server database.
$config['sess_storage'] = 'database';
// [OB] additional config items: You can leave these as defaults for a standard session
$config['sess_data_cookie'] = 'ci_session_data';
$config['sess_database'] = 'default';
$config['sess_timeout'] = 0;
$config['sess_destroy_on_timeout'] = FALSE;
$config['sess_update_interval'] = 180;
$config['sess_gc_probability'] = 10;
$config['sess_http_only'] = FALSE;
$config['sess_secure'] = FALSE;
$config['sess_forwarded_ip'] = FALSE;
sess_cookie_name None Name of the session cookie: default is 'ci_session'
sess_expiration None Time in seconds for session expiry : Set to zero for expiry on browser exit
sess_encrypt_cookie TRUE/FALSE Default is FALSE. TRUE will encrypt the cookie data.
sess_table_name None Name of the session table in the database : Note, Database and table must exist prior to use
sess_match_ip TRUE/FALSE Default FALSE. TRUE will match the user agent's IP address
sess_match_useragent TRUE/FALSE Default TRUE. TRUE will match the identifying browser agent
sess_storage None Where to store User Data : Default is 'cookie'. This setting must contain either 'cookie', to store session data in a cookie, OR 'database', to store session data on the server in a database.
sess_data_cookie None If sess_storage is 'cookie', session data is stored in a second "data cookie". The default name for this cookie is 'ci_session_data'
sess_database None The database connection group to use. By default the 'default' group specified in /config/database.php is used. Add a new group if you want to use a different database for the session.
sess_timeout None Absolute time in seconds after which the session will Time Out. Set to zero for never.
sess_destroy_on_timeout TRUE/FALSE TRUE will destroy the session on timeout : FALSE will re-generate the session id, saving the existing session data
sess_update_interval None Numer of seconds which elapse before the session is updated. Set higher to reduce system load
sess_gc_probability 10 Probability percentage that garbage collection will delete expired session rows from table. Default 10, Always 100, Never 0
sess_http_only TRUE/FALSE For PHP 5.2 or higher, set to TRUE to enable a session cookie which cannot be read via javascript. NB!! Do NOT enable if not running PHP 5.2, your cookies will crumble! Supported on IE 6SP1 and IE7.
sess_forwarded_ip TRUE/FALSE Default is FALSE, the Client or Remote IP is used. If Enabled, and a valid X_FORWARDED_FOR IP exists, it will be used instead. May be of some use if clients are behind a transparent proxy.
sess_secure TRUE/FALSE Set a cookie that will only be accepted if the connection is secure (https / ssl protocol). Default is FALSE

The config setting "sess_use_database" has been removed.

Nota Bene: 1
"last_visit" has been removed entirely. The existing CI library has a bug which never updates it, so I doubt anyone was actually utilising this variable.
The original session cookie data layout was amended as follows:

  1. Old [ session_id ] > New [ session_id ] : Stores the unique session identifier
  2. Old [ ip_address ] > New [ session_start ] : Stores a timestamp marking session initiation
  3. Old [ user_agent ] > New [ session_last_activity ] : Stores a timestamp updated periodically
  4. Old [ last_activity ] > New [ session_ip_address ] : Stores the requesting agents Internet address
  5. Old [ last_visit ] > New [ session_user_agent ] : Stores the requesting agents identifier

These session data variables are prefixed with "session_" and are treated differently to application User Data. Do not use userdata variable names that begin with "session_", you will get unpredictable results.

Nota Bene: 2 :: OBSession version 2.0

The config setting "sess_send_header" has been removed.

The session scheme is amended follows:
The "session cookie" now only contains the session id. It is not encrypted. This cookie is only set once per session , so there is less "Set-Cookie" header traffic.
If you configure session storage on the client via "sess_storage = cookie" a second cookie is set to store the session control data and the user data. This cookie can be optionally encrypted.

If you configure session storage on the server via "sess_storage = database" then all session control data and user data is stored in the sessions table in the server database.

End of Nota Bene

The changes to the cookie layout also affect the layout of the ci_sessions table. If you are using a database, you will need to create a new database table for session usage. (or alter an existing table). MySQL example:
CREATE TABLE IF NOT EXISTS `ci_sessions` (
session_id varchar(40) DEFAULT '0' NOT NULL,
session_start int(10) unsigned DEFAULT 0 NOT NULL,
session_last_activity int(10) unsigned DEFAULT 0 NOT NULL,
session_ip_address varchar(16) DEFAULT '0' NOT NULL,
session_user_agent varchar(50) NOT NULL,
session_data text default '' NOT NULL,
PRIMARY KEY (session_id)
);

SQlite example:
CREATE TABLE ci_sessions (
session_id TEXT PRIMARY KEY NOT NULL DEFAULT '0'
session_start INTEGER NOT NULL DEFAULT 0
session_last_activity INTEGER NOT NULL DEFAULT 0
session_ip_address TEXT NOT NULL DEFAULT '0'
session_user_agent TEXT NOT NULL
session_data TEXT NOT NULL DEFAULT ''
);

Postgre example:
CREATE TABLE ci_sessions (
session_id varchar(40) DEFAULT '0' NOT NULL,
session_start int4 DEFAULT 0 NOT NULL,
session_last_activity int4 DEFAULT 0 NOT NULL,
session_ip_address varchar(16) DEFAULT '0' NOT NULL,
session_user_agent varchar(50) NOT NULL,
session_data text DEFAULT '' NOT NULL,
CONSTRAINT ci_sessions_pkey PRIMARY KEY (session_id)
) ;

Every Which Way but Loose

Notes on using OBSession with a Database:
If you enable the database option, your session data will be stored in a database table, one row per session id.
Every time a session cookie is read, the class also checks that a corresponding session exists in the database. If it does not, the existing session cookie will be deleted and a new session started.

If you explicitly call sess_destroy() when, for example, a user clicks "log_out", the session cookie is deleted, and the session row is deleted from the ci_sessions table.

As users visit your site, session rows will be added to the database. As these sessions expire, the expired rows will be automatically deleted from the table. You do not have to do anything manually!
Note that once the session cookie is expired or deleted, your session is effectively destroyed, irrespective of what is in the database

To reduce load on the system, expired sessions are deleted based on a probability percentage. The default setting is 10. What that means is that every time the class runs garbage collection, an expired session row has a 10 percent chance of being deleted.
You can now configure this percentage. Setting it to 100 will cause all expired session rows to be deleted.

Rest assured, your expired sessions will be garbage collected from the DB, just not immediately!

Cave Canum:
In order to enable sessions which expire on browser exit, a simple strategem is utilized. As the class has no way of knowing when the user will close the browser, It assumes that the session length will be 12 hours. The assumption is that 99.9% of users will close the browser within that time.
The net effect is this: If you set an sess_expiration of zero, the session cookie will be deleted when the user closes the browser. The session will no longer exist, however, your session table will contain session rows which will remain unexpired for at least 12 hours. After that they will be garbage collected.

The implication is that you cannot determine the number of active users online by simply counting unexpired session rows.

The Bridge over the River Kwai.

Library usage is unchanged: Set / Retrieve session userdata with $this->session->set_userdata('name', $user_name);
// OR pass an array Eg;
$newdata = array('page' => 'catalog', 'page_num' => $page_num, 'name' => $user_name);
$this->session->set_userdata($newdata);

$name = $this->session->userdata('name');
For those not accustomed to the luxury, you can set "flash data". Flash data are session data (variables) which persist for only one page load, and are then automatically deleted. You can use flashdata to inform the user of actions taken, or for more exotic uses. Flash data variables are prefixed with "flash_", so do not use this name for your session variables.

  1. You update a users profile, set a "save succeeded" flash message, and redirect to another page
  2. Your user clicks an "Add to Cart" link, you set a flash message "Item X added to cart" and redirect to another page
  3. Use the flash data to implement "one time only" links to prevent repeated downloads from the same page
  4. Use the flash data to make it easier to restore POST data when processing forms (Eg spelling checker)
$this->session->set_flashdata('msg', 'Save succeeded');
// OR pass an array
$newdata = array('item1' => 'porsche', 'item1_amount' => '$325,000.00', 'msg' => 'Good Choice!');
$this->session->set_flashdata($newdata);

$flash_msg = $this->session->flashdata('msg');

As of Version 2.0 a new type of flash data is enabled. so-called "Read-Once" flash data. This is implemented as ordinary userdata, which will be automatically deleted once it is read. A read-once function is provided for this. Read-Once flash data is useful if you need the data to persist across page loads, until you access it, for example to implement a one time download facility. Note. You can access your variable at any time with $this->session->userdata('name') and the data will persist. Once you access your data with $this->session->ro_userdata('name'), the variable is unset, and will no longer exist. $this->session->set_userdata('msg', 'download link');
$flash_msg = $this->session->ro_userdata('msg');

There are a couple of convenience functions added: $session_id = $this->session->id() Simply returns the current session id. (FALSE if not set) $some_array = $this->session->all_userdata() Returns an array of the UserData in the session. (instead of one item at a time) $this->session->regenerate_id() Will generate a new session id, saving the existing session data and User Data. You might want to call this manually after a login for example, rather than automatically re-generating the session periodically. Good security practise is to re-generate the session whenever there is a privilege change.

From Here to Eternity

A new session option is enabled for servers running PHP version 5.2 or better only! You can now set the HttpOnly parameter on the session cookie to TRUE. This will set a cookie which cannot be read via javascript client side.
This adds some extra protection against XSS attacks. (My understanding is that javascript can still write to the cookie, so this appears to be of only limited help.)

Currently this option is only supported by Microsoft browsers like IE 6SP1 and IE7.
It is not part of the "official" cookie spec yet. It seems to work well in these browsers. FireFox has an addon which claims to enable HttpOnly, but I found it was actually encrypting the cookie, which is something else altogether. I hear that FireFox version 3 will officially support HttpOnly cookies.)

A Walk in the Sun

A new session option is available to allow the session to use the HTTP_X_FORWARDED_FOR IP address, if a valid IP exists. This may be useful for when clients are behind a transparent proxy, such as AOL clients. It will return the actual IP client address, and not the REMOTE_ADDR of the proxy. Note. If the proxy is not transparent, or is a proxy for private address space LAN clients, you will probably end up with rubbish anyway. The only IP that is reliable and cannot be spoofed is the REMOTE_ADDR. Also, the forwarded IP may actually consist of a list of IP addresses, only the last one is returned.

Catch Me if You Can

A new session option is available to enable secure sessions via SSL / https connections. Enabling this option will set cookies that are only accepted over secure connections. If the connection is not secure the cookie will not be set.

Honey, I shrunk the Kids.

The standard PHP session handler sends cache control headers based on the session.cache_limiter setting. Instead of configuring this in OBSession, I would recommend that cache control be done within your application.
That allows for more control by the developer, and avoids potential conflicts. You can easily set headers in CI via the Output class. The code below will prevent your session based pages from being cached.

The same approach applies to sending headers to implement P3P Privacy Policies.

$this->output->set_header("Cache-Control: no-store, no-cache, must-revalidate");
$this->output->set_header("Cache-Control: post-check=0, pre-check=0", false);
$this->output->set_header("Pragma: no-cache");

This is a somewhat experimental addition for dealing with Microsoft Internet Explorer and Privacy Policy (P3P)

Note: This has been removed in Version 2.0

Internet Explorer implements the W3C proposed Privacy Policy Protocol roughly as follows:
If a domain sets any kind of cookie, the browser (with a default privacy setting of "medium") will check to see if the website has a Compact Privacy policy. If not, cookies may be downgraded, restricted or blocked.

This may affect cookie based sessions, particularly with IE7 and sites using iFrames. The "second party" domain is seen as a "third party" and the cookie is blocked. This results in IE 6 or 7 users being "logged out" of sessions.

As an experiment, I have added the ability to send an optional server header before the session cookie is sent.
The default is to NOT send a header and the config setting is 'sess_send_hdr' = ''; (an empty string).
You can use it to send a P3P compact policy. Set your config file for example to: sess_send_hdr = 'P3P: CP="CAO PSA OUR"';

Please note I only have access to a buggy version of IE6 on WinMe, it appears to eat cookies no matter where they are from or what the privacy setting is. If anyone wants to test this out on IE7, feedback will be welcomed.

Hitchhiker's guide to the Universe.

This page can be found at obsession
A zip file with all the goodies can be downloaded from obsession.zip

Unzip the contents of obsession.zip into a temp directory. Create a new codeigniter application under your web servers document root. Copy the file Session.php to the /application/libraries/ directory. Copy the files config.php and database.php to your /application/config/ directory. Amend as needed. Copy the files welcome.php and control.php to your application/controllers/ directory. Finally copy all the *_view.php files to your application/views directory.

Check that your config settings match your local setup. Check that the default route is "welcome".
Point your browser to something like http://localhost/test_sess and you should see a page load with the heading : "Welcome to :: Login" , that's your que to click on the "Login" link and start testing.

Updates : 29 April 2008

This release is Version 2.0.2 of OBSession

    Changes : Thank you Wades!
  1. Bugfix : Sessions with [sess_expiration] > 0, where the session is active (user reloads a page within expiration time) were incorrectly expired, instead of being extended
  2. Update your library from Version_two_Session.phps
NOTE: The zip file has not been updated, please use the file above. Save as Session.php and overwrite your previous library file.

Updates : 27 June 2007

This release is Version 2.0.1 of OBSession

    Changes :
  1. Bugfix : Session did not work if cookie encryption and database storage were enabled.
  2. Update your library from Version_two_Session.phps
NOTE: The zip file has not been updated, please use the file above.

Updates : 21 May 2007

This release is Version 2.0 of OBSession

The previous version can be downloaded here Version_one_Session.phps
NOTE: I will continue to maintain this previous version, for bug fixes, but I will no longer be enhancing it.

Upgrade notes: There is no change to the session table schema, so you can use your existing table data.

The most significant change is that the session cookie now only contains the session ID. The most likely outcome of an upgrade is that when the browser presents a session cookie set with an earlier version of OBSession, the new version will not accept the cookie, and a new session will be initiated. If your existing sessions expire when the browser is closed, then this will not be an issue.

    Changes : New Session library v2.0 released : To upgrade please download latest files.
  1. Session cookie now only contains a session identifier token
  2. If storing userdata in a cookie, a second, session data cookie is written
  3. You can configure the session to use a database other than the one in the default connection group
  4. An additional FlashData type is implemented. Read-Once userdata that is deleted when it accessed
  5. Setting secure cookies is enabled
  6. Optionally, the X_FORWARDED_FOR IP address will be returned if a valid one exists.
  7. The Demo / Test application has been upgraded and hopefully provides more useful test information.
  8. The Demo application is now available for testing online tryme
  9. Please download the new release from here obsession.zip
  10. The OBSession class file is available here Version_two_Session.phps
  11. API class documentation is available in CHM format obsession_api_doc.chm

Updates : 01 May 2007

Important ! This is a Bug Fix release. (Thanks to qwstor for reporting it.)

    Changes : Session library has been updated! : NB! Please download latest files.
  1. Fixed: Check that a session id exists in sess_destroy() before deleting session row. (If database option is enabled)
  2. The updated library can be downloaded here Current_Session.php.txt
  3. The zip file obsession.zip has been updated

Updates : 15 April 2007

    Changes : Session library has been updated! : Please download the latest zip file.
  1. Documentation has been updated and (hopefully) improved
  2. Minor changes and additions to the demo code
  3. Function sess_destroy() will now also delete the session row, if storage is 'database'
  4. Added ability to set the Garbage Collection Probability percentage via a config entry
  5. Added ability to pass an array or a string parameter to function set_flashdata() [Thx agraddy]
  6. Added ability to optionally send a full server header before the cookie is sent [for P3P]
  7. Added ability to optionally set the session cookie as HttpOnly for PHP v 5.2 or greater
  8. The zip file obsession.zip has been updated

Updates : 25 March 2007

    Changes : No changes to Session library!
  1. Some typos and errors were fixed in the documentation
  2. The demo / test code now demonstrates a login procedure, using a "remember me" cookie.
  3. The zip file obsession.zip has been updated

Updates : 14 March 2007

Thanks to some excellent feedback from forum members, some things have been fixed or made clearer.

    Changes : Please download the updated session class from Session.phps.txt
  1. The session class had some function names which were incompatible with CI_Session.
  2. Some typos and errors were fixed in the documentation
  3. The zip file obsession.zip has also been updated

The Good, The Bad, and the Ugly.

Kudos to Rick Ellis, for writing the original. Thanks To Dariusz Debowczyk & Dready for writing much of the new lib code. And hello to all the folk at Code Igniter Forums.

Written by Oscar Bajner : Licensing and copyright information CI License

I have tested the code *carefully*, I guarantee there's probably still BUGHs in them thar hills, use at your own peril.