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
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
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 :
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.
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.
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;
Setting | Option | Description |
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:
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: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)
) ;
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.
Library usage is unchanged:
Set / Retrieve session userdata with
$this->session->set_userdata('name', $user_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.
// 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');
$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.
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 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.
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.
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.
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.
This release is Version 2.0.2 of OBSession
This release is Version 2.0.1 of OBSession
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.
Important ! This is a Bug Fix release. (Thanks to qwstor for reporting it.)
Thanks to some excellent feedback from forum members, some things have been fixed or made clearer.
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.