The Session Library permits you maintain a user's "state" and track their activity while they browse your site. The Session Library stores session information for each user as serialized (and optionally encrypted) data in a cookie. It can also store the session data in a database table or in a plain text file for added security, as this permits the session ID in the user's cookie to be matched against the stored session ID. By default only the cookie is saved. If you choose to use the database option you'll need to create the session table as indicated below.
Initializing a Session
Sessions will typically run globally with each page load, so the Session Library must either be initialized in your controller, or it can be auto-loaded by the system. For the most part the Session Library will run unattended in the background, so simply initializing the library will cause it to read, create, and update sessions.
To initialize the Session Library manually in your controller, use the rigLoaderLoadLibrary handler:
Note: Keep in mind, if gConfig["sess_driver"] is set to "database" in your config file, that initializing the Session Library connects to your database using the default connection group specified in your database config file. If you need to choose another connection group connect to your database before initializing the Session Library.
How do Sessions work?
When a page is loaded, the Session Library will check to see if valid session data exists in the user's session cookie. If sessions data does not exist (or if it has expired) a new session will be created and saved in the cookie. If a session does exist, its information will be updated and the cookie will be updated. With each update, the session_id will be regenerated.
It's important for you to understand that once initialized, the Session Library runs automatically. There is nothing you need to do to cause the above behavior to happen. You can, as you'll see below, work with session data or even add your own data to a user's session, but the process of reading, writing, and updating a session is automatic.
What is Session Data?
A session, as far as revIgniter is concerned, is simply an array containing the following information:
- The user's unique Session ID (this is a statistically random string with very strong entropy, hashed with md5 for portability, and regenerated (by default) every five minutes)
- The user's IP Address
- The user's User Agent data (the first 50 characters of the browser data string)
- The "last activity" time stamp.
The above data is stored in a cookie as a serialized array with this prototype:
tArray["session_id"] -- random hash tArray["ip_address"] -- "string - user IP address" tArray["user_agent"] -- "string - user agent data" tArray["last_activity"] -- timestamp
If you have the encryption option gConfig["sess_encrypt_cookie"] enabled, the serialized array will be encrypted before being stored in the cookie, making the data highly secure and impervious to being read or altered by someone. More info regarding encryption can be found here, although the Session Library will take care of initializing and encrypting the data automatically.
Note: Session cookies are only updated every five minutes by default to reduce processor load. If you repeatedly reload a page you'll notice that the "last activity" time only updates if five minutes or more has passed since the last time the cookie was written. This time is configurable by changing the gConfig["sess_time_to_update"] line in your system/config/config.lc file.
Retrieving Session Data
Any piece of information from the session array is available using the following function:
Where item is the array index corresponding to the item you wish to fetch. For example, to fetch the session ID you will do this:
put rigSessUserdata("session_id") into tSessionID
Note: The function returns FALSE (boolean) if the item you are trying to access does not exist.
To get all session data as an array simply omit the key parameter.
Adding Custom Session Data
A useful aspect of the session array is that you can add your own data to it and it will be stored in the user's cookie. Why would you want to do this? Here's one example:
Let's say a particular user logs into your site. Once authenticated, you could add their username and email address to the session cookie, making that data globally available to you without having to run a database query when you need it.
To add your data to the session array involves passing an array containing your new data to this function:
Where tArray is an associative array containing your new data. Here's an example:
put "johndoe" into tNewData["username"] put "firstname.lastname@example.org" into tNewData["email"] put TRUE into tNewData["logged_in"] rigSetSessUserdata tNewData
If you want to add userdata one value at a time, rigSetSessUserdata also supports this syntax.
rigSetSessUserdata "someName", "someValue"
Note: Cookies can only hold 4KB of data, so be careful not to exceed the capacity. The encryption process in particular produces a longer data string than the original so keep careful track of how much data you are storing.
Removing Session Data
Just as rigSetSessUserdata can be used to add information into a session, rigUnsetSessUserdata can be used to remove it, by passing the session key. For example, if you wanted to remove "someName" from your session information:
This handler can also be passed an associative array of items to unset.
put "" into tArrayItem["username"] put "" into tArrayItem["email"] rigUnsetSessUserdata tArrayItem
revIgniter supports "flashdata", or session data that will only be available for the next server request, and are then automatically cleared. These can be very useful, and are typically used for informational or status messages (for example: "record 2 deleted").
Note: Flash variables are prefaced with "flash" so avoid this prefix in your own session names.
To add flashdata:
rigSetSessFlashdata "item", "value"
You can also pass an array to rigSetSessFlashdata, in the same manner as setSessUserdata.
To read a flashdata variable:
Or to get an array with all flashdata, simply omit the key parameter:
If you find that you need to preserve a flashdata variable through an additional request, you can do so using the rigKeepSessFlashdata handler.
To mark an existing session array item as "flashdata":
You can pass an array to rigSessMarkAsFlash like in the following example:
put "" into tExistingItemsArray["username"] put "" into tExistingItemsArray["logged_in"] rigSessMarkAsFlash tExistingItemsArray
revIgniter supports session data items with a specific expiration time. After the value expires, or the session expires or is deleted, the session array item is automatically removed.
To add tempdata:
rigSetSessTempdata "item", "value", 300
The third parameter is the time-to-live value in seconds.
You can also pass an array to rigSetSessTempdata like in the following example:
put "johndoe" into tTempDataA["username"] put TRUE into tTempDataA["logged_in"] rigSetSessTempdata tTempDataA
To read a tempdata variable:
Or to retrieve all existing tempdata as an array, simply omit the key parameter:
To mark an existing session array item as "tempdata", simply pass its name and time-to-live (in seconds!) to the rigSessMarkAsTemp handler:
rigSessMarkAsTemp "item", 300
You can pass an array to rigSessMarkAsTemp like in the following example:
put "" into tExistingItemsArray["username"] put "" into tExistingItemsArray["logged_in"] rigSessMarkAsTemp tExistingItemsArray, 240
Note: If the expiration parameter is omitted the default time-to-live value of 300 seconds will be used.
While the session data array stored in the user's cookie contains a Session ID, unless you store session data in a database or in a file on your server there is no way to validate it. For some applications that require little or no security, session ID validation may not be needed, but if your application requires security, validation is mandatory.
When session data is available in a database, every time a valid session is found in the user's cookie, a database query is performed to match it. If the session ID does not match, the session is destroyed. Session IDs can never be updated, they can only be generated when a new session is created.
In order to store sessions in a database, you must first create a database table for this purpose. Here is the basic
prototype required by the Session Library.
CREATE TABLE IF NOT EXISTS `ri_sessions` ( `session_id` varchar(40) NOT NULL DEFAULT '0', `ip_address` varchar(45) NOT NULL DEFAULT '0', `user_agent` varchar(120) NOT NULL, `last_activity` int(10) unsigned NOT NULL DEFAULT '0', `user_data` text, PRIMARY KEY (`session_id`) );
CREATE TABLE ri_sessions ( session_id varchar(40) DEFAULT 0 NOT NULL, ip_address varchar(45) DEFAULT 0 NOT NULL, user_agent varchar(120) NOT NULL, last_activity integer DEFAULT 0 NOT NULL, user_data text, PRIMARY KEY(session_id), CONSTRAINT check_last_activity CHECK(last_activity >= 0) );
CREATE TABLE "main"."ri_sessions" ( "session_id" text(40) NOT NULL DEFAULT '0', "ip_address" text(45) NOT NULL DEFAULT '0', "user_agent" text(120) NOT NULL, "last_activity" integer(10) NOT NULL DEFAULT 0, "user_data" text, PRIMARY KEY("session_id") );
Note: By default the table is called ri_sessions, but you can name it anything you want as long as you update the application/config/config.lc file so that it contains the name you have chosen. Once you have created your database table you can enable the database option in your config.lc file as follows:
put "database" into gConfig["sess_driver"]
Once enabled, the Session Library will store session data in the DB.
If you don't use the default table name "ri_sessions" make sure you've specified the name in your config file as well:
put "mySessions" into gConfig["sess_save_location"]
Note: The Session Library has built-in garbage collection which clears out expired sessions so you do not need to write your own routine to do it.
Saving Session Data to a File
Another option to establish session ID validation is to save session data to a file. To use your file system for storing session data set the session driver to "files" in your config file as follows:
put "files" into gConfig["sess_driver"]
You can specify a location to save sessions to by setting gConfig["sess_save_location"] to an absolute path to a writable directory like:
put "/my/absolute/path/to/sessionLocation" into gConfig["sess_save_location"]
If set to empty the standard temporary folder is used.
Similar to the database option when session data is stored in a file, every time a valid session is found in the user's cookie, your storage location is searched for a matching file name. If the session ID does not match, the session is destroyed. Session IDs can never be updated, they can only be generated when a new session is created.
Session directory permissions are automatically set to 0700 so only the directory’s owner is allowed to perform read and write operations on it.
Destroying a Session
To clear the current session:
Note: This handler should be the last one called, and even flash variables will no longer be available. If you only want some items destroyed and not all, use rigUnsetSessUserdata.
Create a new Session
To start over with a new session:
You'll find the following Session related preferences in your application/config/config.lc file:
|sess_cookie_name||ri_session||None||The name you want the session cookie saved as.|
|sess_expiration||129600||None||The number of seconds you would like the session to last. The default value is 36 hours (129600 seconds). If you would like a non-expiring session set the value to zero: 0. Keep in mind that the value is related to server time.|
|sess_expire_on_close||FALSE||TRUE/FALSE (boolean)||Whether to cause the session to expire automatically when the browser window is closed.|
|sess_encrypt_cookie||FALSE||TRUE/FALSE (boolean)||Whether to encrypt the session data.|
|sess_driver||database/files||Whether to save the session data to a database, to a file or in a cookie. You must create the table before enabling the database option. If this option is set to empty all session data is stored in a cookie.|
|sess_save_location||Any valid SQL table name or any valid absolute path to a writable directory respectively. If set to empty the default table name "ri_sessions" or the standard temporary folder respectively is used in case sess_driver is "database" or "files".||The location to save sessions to. Of course this is driver dependant.|
|sess_time_to_update||300||Time in seconds||This options controls how often the session library will regenerate itself and create a new session id.|
|sess_match_ip||FALSE||TRUE/FALSE (boolean)||Whether to match the user's IP address when reading the session data. Note that some ISPs dynamically changes the IP, so if you want a non-expiring session you will likely set this to FALSE.|
|sess_match_useragent||TRUE||TRUE/FALSE (boolean)||Whether to match the User Agent when reading the session data.|
Note: Keep in mind that the current time used to calculate the session expiration date is referenced either to your server's local time or GMT, based on the "time reference" setting in your config file.