Accessibility
Icon or Spacer
   
Enabling Session Management in ColdFusion Express
By: Raymond Camden

Editor's Note: This article and supporting code are available in a ZIP archive file. Click here to download.

In 1999, Allaire released a free version of ColdFusion called ColdFusion Express. This version of the ColdFusion server allowed you to use many, but not all, of the features of the ColdFusion Enterprise. One of the features not included is session management. I recommend upgrading to the retail version of ColdFusion to take advantage of this functionality, but if you're on a limited budget, this article will offer a short-term fix that will tide you over till you can purchase the retail version. Our solution will use the power of Client variables, a feature included in ColdFusion Express as well as the retail version of ColdFusion.

What Are Sessions?

Simply put, a session is defined as a particular user's visit to a Web site. Under ColdFusion, sessions work like so:
  1. As soon as a user accesses the application, the server "tags" them with a unique identifier. This is done with cookies (although sessions can be used without cookies).
  2. Because this particular cookie only exists on one user's machine, ColdFusion can associate values with that user. These values will only exist for a particular user. So, one user may have a session variable called Color that has a value of "blue," while another user may have a value of "red" for their copy of the Color variable.
  3. A session implies that the user is accessing the site. If the user does not return for a certain amount of time, let's say 30 minutes, the server will automatically reset the session variables for that user. Imagine browsing a Web site at a coffee shop. When you get up and leave, the machine may be idle for a while before someone else sits down at the machine. ColdFusion interprets that idleness as a change in users.
Using sessions in ColdFusion is pretty simple. In the application.cfm file of your application, you use the <CFAPPLICATION> tag like so:


<CFAPPLICATION NAME="TestApplication" SESSIONMANAGEMENT=True>

Once you've done that, you can use session variables by simply setting and outputting variables within the session scope.

Example:

<CFSET Session.Color = "red">

<CFOUTPUT>
You have chosen to use #Session.Color# as your background color.
</CFOUTPUT>

Pretty easy. But if you turn on session management in ColdFusion Express, nothing happens. How can we create a system that is like ColdFusion Enterprise's session management feature?

Faking the Session Scope

Let's begin by creating a simple application. We will use session management to handle the security of this application, so most of our work will be in the application.cfm and login.cfm files. Let's begin by taking a look at the application.cfm. This is where all of the work is done.

Listing 1.1 (application.cfm):
<CFAPPLICATION NAME="TestApplication" CLIENTMANAGEMENT="Yes" SETCLIENTCOOKIES="Yes">

<!--- Session Hack --->

<CFPARAM NAME="Application.Sessions" DEFAULT="#StructNew()#">
<CFPARAM NAME="Application.SessionTimeout" DEFAULT="10">
<CFIF NOT StructKeyExists(Application.Sessions,URLTOKEN)>
	<CFSET Application.Sessions[URLTOKEN] = StructNew()>
<CFELSE>
	<!--- garbage collection --->
	<CFIF DateDiff("n",Client.LastVisit,Now()) GT Application.SessionTimeout>

		<CFSET Application.Sessions[URLTOKEN] = StructNew()>
	</CFIF>
</CFIF>
<CFSET Session = Application.Sessions[URLTOKEN]>
<!--- End Session Hack --->

<!--- Fake logon --->
<CFIF IsDefined("Form.FakeLogon")>

	<CFSET Session.LoggedIn = True>
</CFIF>

<CFIF NOT IsDefined("Session.LoggedIn")>
	<CFINCLUDE TEMPLATE="logon.cfm">
	<CFABORT>
</CFIF>
Let's take a look at this file line by line. As with all ColdFusion applications, we begin with the <CFAPPLICATION> tag. The only really important part of this tag is the fact that we turn on client management. This is important even if we don't use client variables. When we turn on client management, ColdFusion automatically assigns a URLTOKEN variable. This variable is used in both ColdFusion Express and ColdFusion Enterprise to enable you to use session, or client vars, without cookies. It consists of the CFID and CFTOKEN that ColdFusion uses to uniquely identify you. Here's a sample value:

CFID=1&CFTOKEN=80586340
We also use the client variable, LastVisit, to determine how long ago you last hit the site. This will help us later on. (The point here is that ColdFusion is already doing a lot of work for us, so why not let the server take care of what it can?)

Now comes the fun part. We will store our sessions in an application variable, so the first thing we do is create the variable. Of course, we don't want to recreate it each time, so we use the <CFPARAM> tag to ensure it is only created once. The variable, Application.Sessions, will store our sessions. We want this variable to be a structure, so we pass in the StructNew() function as the default. We then define a timeout for our application and store it in the application variable, SessionTimeOut. This is going to work the same way the SESSIONTIMEOUT attribute does in the <CFAPPLICATION> tag. If the user has not hit the site in the last X minutes, then we terminate their session. I have set the timeout value for this application to be ten minutes.

We will store the particular session values for the current user by using the URLTOKEN variable as the key of the Application.Sessions structure. We first check to see if we have already created a structure for the particular value of URLTOKEN. We do this using the StructKeyExists function. If the key does not exist, we simply create it with this line:

<CFSET Application.Sessions[URLTOKEN] = StructNew()>
We use the StructNew() function to create a substructure beneath the main Application.Sessions structure. If the key does exist for this particular URLTOKEN, we then need to check to see if it has expired. Using the DataDiff() function along with the Client.LastVisit variable, we can quickly see if this particular user has not hit the site in the last ten minutes. If the user's session needs to be expired, we simply reset the structure using the StructNew() function. (Note: Because ColdFusion has short-circuit Boolean evaluation, we could have combined the CFIF/CFELSE statement into one CFIF. To make things easier for the reader, I have kept the two checks separate.)

Once we are assured that we have a structure just for our user, how do we enable the session scope? We simply create a reference to it using this line:

<CFSET Session = Application.Sessions[URLTOKEN]>
By directly assigning one structure to another, ColdFusion doesn't create a copy; rather it creates a pointer. When I change something in Session, it will be reflected in Application.Sessions[URLTOKEN]. With this one simple line, I can now assign any variable to the Session structure, just as if I were using "real" session management under ColdFusion Enterprise (or Professional).

That's all it takes for our session "hack." The rest of the application.cfm file is just like any other application. We have two <CFIF> clauses that will take care of the security of our application. Because this is only a demo, we log a person on if the form variable "FakeLogon" is passed. This is where you would normally run a CFQUERY to validate a username and password. As you can see, we simply set the session variable, LoggedIn, to true. This is just like using session variables in the "real" ColdFusion. The next <CFIF> block checks to see if we have the Session.LoggedIn variable defined. If we don't, then we force the user to the logon page. (This page is included in the zip file for this article. It's an extremely simple form so I won't discuss it here.)

That's all there is to it. In the included zip file, index.cfm and page2.cfm show simple examples of setting and reading session variables. Because this is no different than what you would do using ColdFusion Enterprise, I will not spend any time describing the code here. As I said at the beginning of the article, it is still recommended that you upgrade to ColdFusion Professional or Enterprise if you want to use session management and other high-level features, but hopefully this will help you get more out of a great, and free, product.

About the Author

Raymond Camden is Webmaster of the Death Clock, a "ColdFusion Jedi Master" for Syntegra, an Allaire Certified Instructor, and Member of Team Allaire. You can reach him at raymond.k.camden@syntegra.com.