Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at the jQuery Conference 2011 (Cambridge, MA) with:

Ask Ben: Testing For ColdFusion Session Management

By Ben Nadel on

Ben, Do you know how I can test to see if the session scope exists if session management is turned off. I turned off session management and did an isDefined('session') which returned yes. I'm trying to do this before a StructKeyExists(session,'temp'). StructKeyExists throws an exception if the structure doesn't exist, but I don't know how to test for the absence of the session!

At first, I have to say that I didn't believe you; I couldn't believe that the SESSION would be "defined" if ColdFusion session management was turned off. But, after trying it for myself, sure enough, it is defined. In fact, not only is it defined, but you can CFDump it out. It comes up as an empty struct, but it doesn't throw an exception.

To help us in this matter, there is a nice little UNDOCUMENTED function in the ColdFusion APPLICATION scope that allows us to view the application settings. This function, GetApplicationSettings(), is called directly on the APPLICATION scope in dot-notation:

  • <!---
  • Dump out ColdFusion application settings. This will
  • give us insight into most of the application-level
  • settings that can be set in the Application.CFM/CFC.
  • --->
  • <cfdump
  • var="#APPLICATION.GetApplicationSettings()#"
  • label="GetApplicationSettings() Output"
  • />

Running the above code, we get the following CFDump output:


 
 
 

 
APPLICATION.GetApplicationSettings() Returns Struct Of Application Level Settings  
 
 
 

As you can see, this returned struct gives us access to most, but not all, of the settings that we can set in the Application.cfm/cfc files. The one that we are most concerned with right now is the SessionManagement key which will give us the boolean value as to whether or not session management has been enabled.

To test this, I have set up a tiny ColdFusion Application.cfc file in which session management has been turned off:

  • <cfcomponent
  • output="false"
  • hint="Handles application level events.">
  •  
  • <!--- Define application settings. --->
  • <cfset THIS.Name = "CheckSessionTest" />
  • <cfset THIS.ApplicationTimeout = CreateTimeSpan( 0, 0, 1, 0 ) />
  • <cfset THIS.SessionManagement = false />
  •  
  • </cfcomponent>

Then, I set up a tiny index.cfm file to test for ColdFusion session management:

  • <!---
  • Check to see if Session Management has been enabled
  • in this ColdFusion application.
  • --->
  • <cfif APPLICATION.GetApplicationSettings().SessionManagement>
  •  
  • <p>
  • SESSION Is Enabled
  • </p>
  •  
  • <cfelse>
  •  
  • <p>
  • SESSION Is Disabled
  • </p>
  •  
  • </cfif>

Running the above code, we get the following output:

SESSION Is Disabled

Works quite nicely. Now, like I said before, this is an undocumented feature, so use it at your own discretion. One of the things that I do in some of my applications where ColdFusion Session Management might be toggled on and off is to set a flag in the REQUEST scope, such as REQUEST.HasSessionScope. This way, whatever logic performs the application settings can also set the REQUEST flag.

Hope that helps a bit.



Looking For A New Job?

100% of job board revenue is donated to Kiva. Loans that change livesFind out more »

Reader Comments

Instead of using an undocumented function (which means it could be removed or changed at any time), why not just use a try/catch block to try and set a session variable, and create a flag accordingly?

Reply to this Comment

@Brian,

Good question. People seem to rag on me anytime I used "on purpose" exception throwing to do anything, especially anything that will be done on a regular basis. I guess, the best of all possible worlds would be to encapsulate the function and USE the undocumented features. Then, if they ever get taken out, it only needs to be changed in the function (to use CFTry / CFCatch) and the rest of the code still works.

Also, that way, since exception handling is a bit expensive in terms of processing (or so I am harassed!), this way, you only need to use it when CF changes.

Reply to this Comment

Another approach would be to set a session variable, redirect to another page, then check if the variable isDefined().

Reply to this Comment

@Tom,

True, like testing a cookie value, but that might not be the easiest thing if you are dealing with a single page request or something.

Reply to this Comment

The purpose of all this was that upon reiniting my application, I would always get an error because I set the timeout of app and session to be 0 and the page would then process without a session scope.

So, I thought, I'd just put some logic in so that I don't get this error but I couldn't figure out how. It just seemed quirky to me.

Of course, the easy fix for the above is to set the session and application timeout to 1 second upon reinit.

Reply to this Comment

@Justin,

Yeah, I would go that way. It's probably always easier to have SOME session scope, even if its timeout is very short. Even Michael Dinowitz does that and he is the King of conditional session management.

Reply to this Comment

Yeah that's the way I did it, but it's always good to see the other perspective. I always wanted to make sure I wasn't loony about the whole session being defined with sessions turned off thing.

Reply to this Comment

Dang! This always happens :) I find out something and then I find out that it was already discussed years ago! Oh well, at least I learned something from this.

Reply to this Comment

a little more tricky situation here - i have a view that uses an expression that involves a session scope variable; there is a context in which this view gets called whereby i haven't even determined the application name yet (this.name in the Application.cfc is dynamically determined) so in this context, i cannot access application.GetApplicationSettings() either; i had always though isDefined for either the session scope or the application scope would simply return false if their was no <cfapplication tag or Application.cfc name in play - but alais, its just boots an error - so it seems i have to use the try catch methodology... the good news, this situation is only on a dummy login screen that appears only in our dev environment so the "tax" factor doesnt weigh into our prod environment. does anyone know a non try-catch way to see if an application context has been established yet in the request??

Reply to this Comment

@Jon,

If the application name isn't even defined at that point, I don't think there is a non-try/catch way as the session management is tied to a given application. And, if it's not defined yet, then I don't think session management is actually defined yet.

Reply to this Comment

Hi ben,

I am fairly new to coldfusion.
I am looking to set up a session variable to display Recently viwed items.

I cannot figure out how in Coldfusion.

Can you help me out?

Reply to this Comment

Since I am doing shared hosting, I am not able to use the cfdump function because it blocks our ability to create objects! I am trying to see why the session is not re initialized once a user logs off from the site (clearing all session.
<cfloop collection=#session# item="i">
<cfset StructDelete(session,i)>
</cfloop>
What am I doing wrong? Please help.

Reply to this Comment

@Fernando,

When a user makes a request to the ColdFusion server, the browser posts all of the cookies for the given domain (roughly). In those cookies are the CFID / CFTOKEN values; typically (this can be changed) these cookies are what identify your browser with a given session.

By clearing the SESSION object, all you're doing is clearing the information IN the session; you're not actually killing the association between the browser and the session. If you want to do that, you actually need to *expire* the session cookies.

If you want to actually get your onSessionEnd() event handler to fire, however, that is a tricky thing that I have not been able to nail down - that's really determined by the ColdFusion framework.

Does that help at all?

Reply to this Comment

"In fact, not only is it defined, but you can CFDump it out. It comes up as an empty struct, but it doesn't throw an exception."

It appears that in CF9 it does now throw an exception if you attempt to dump the session struct if session management is not enabled.

Reply to this Comment

@Richard,

Good to know. It sounds like to be on the safe side, you probably never want to dump out the Session scope unless you're sure session management is enabled.

Reply to this Comment

To follow up my own ages ago comment above;

isDefined('Session.foo')

will throw (in CF9 anyway)

The requested scope session has not been enabled.Before session variables can be used, the session state management system must be enabled using the cfapplication tag.

if the Application.cfc sets session management to off, so the only way to safely dump session variables in something like a global error page is to check

APPLICATION.GetApplicationSettings().SessionManagement

first

Reply to this Comment

Well the disadvantage of using undocumented features is that the vendor (Adobe) is not obliged to maintain it. CF10 no longer has this value in the getApplicationSettings() returned structure. For the life of me, I don't know why -- just another gotcha.

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.