Using Session Timeout And CreateTimeSpan() - Subtle Caveat

Posted March 30, 2007 at 2:18 PM

Tags: ColdFusion

CreateTimeSpan() is a really easy way to create timeouts for both your Application and your user Sessions. It takes days, hours, minutes, and seconds and returns the numeric representation of that time span. I am sure most of you, if not all of you, are using this in your CFApplication tags or Application.cfc ColdFusion components.

CreateTimeSpan() is really cool, but it is a method call. A tiny one nonetheless, but a method call that has with it, processing overhead. Is this overhead needed? Not really. Unless you are in the habit of changing your timeouts, most likely all your CreateTimeSpan() calls return a constant value. Well, if they are returning a constant value, why bother using the method call. Readability? Sure. Maintainability? Of course.

But what if you were NEVER going to change the time span value. Could you just put in the value that CreateTimeSpan() would have returned. The answer is quite tricky in its subtlety. You can AND you can't. To demonstrate, I have set up a very simple HTML page:

 Launch code in new window » Download code as text file »

  • <html>
  • <head>
  • <title>Session Timeout Test</title>
  • </head>
  • <body>
  •  
  • <cfoutput>
  •  
  • <p>
  • ID: #SESSION.CFID#<br />
  • Token: #SESSION.CFTOKEN#
  • </p>
  •  
  • </cfoutput>
  •  
  • </body>
  • </html>

All this does is output the SESSION information. Then, I set up an Application.cfc that defines the Application and Session management in several different ways. Depending on which variable I pass in the URL (a,b,c,d), the SESSION timeout is set using a different methodology:

 Launch code in new window » Download code as text file »

  • <cfcomponent>
  •  
  • <cfset THIS.Name = "SessionTimeoutTest" />
  • <cfset THIS.ApplicationTimeout = CreateTimeSpan( 0, 1, 0, 0 ) />
  • <cfset THIS.SessionManagement = true />
  •  
  •  
  • <!---
  • Check to see which session timeout we are
  • going to utilize.
  • --->
  • <cfif StructKeyExists( URL, "a" )>
  •  
  • <!---
  • Here, we are going to try to use the result of
  • the CreateTimeSpan() without calling the method.
  • CreateTimeSpan() for 5 minutes results in the
  • number: 0.00347222222222. Use this instead of
  • the method call.
  • --->
  • <cfset THIS.SessionTimeout = 0.00347222222222 />
  •  
  • <cfelseif StructKeyExists( URL, "b" )>
  •  
  • <!---
  • Try to set an intermediary variable that stores
  • the result of the CreateTimeSpan() method, and
  • then applies that to the application setup.
  • --->
  • <cfset dtTimeSpan = CreateTimeSpan(
  • 0, <!--- Days. --->
  • 0, <!--- Hours. --->
  • 5, <!--- Minutes. --->
  • 0 <!--- Seconds. --->
  • ) />
  •  
  • <!--- Set the sessiontimeout. --->
  • <cfset THIS.SessionTimeout = dtTimeSpan />
  •  
  • <cfelseif StructKeyExists( URL, "c" )>
  •  
  • <!---
  • Try to set an intermediary variable that stores
  • the value we built in "a" and then applies that
  • to the application setup.
  • --->
  • <cfset dtTimeSpan = 0.00347222222222 />
  •  
  • <!--- Set the sessiontimeout. --->
  • <cfset THIS.SessionTimeout = dtTimeSpan />
  •  
  • <cfelseif StructKeyExists( URL, "d" )>
  •  
  • <!---
  • Try to set an intermediary variable that stores
  • the value we built in "a". However, this time,
  • store the value as a Java Double. and then applies
  • that to the application setup.
  • --->
  • <cfset dtTimeSpan = JavaCast(
  • "double",
  • 0.00347222222222
  • )/>
  •  
  • <!--- Set the sessiontimeout. --->
  • <cfset THIS.SessionTimeout = dtTimeSpan />
  •  
  • <cfelse>
  •  
  • <!---
  • For our default, we are just going to use
  • the CreateTimeSpan() directly.
  • --->
  • <cfset THIS.SessionTimeout = CreateTimeSpan(
  • 0, <!--- Days. --->
  • 0, <!--- Hours. --->
  • 5, <!--- Minutes. --->
  • 0 <!--- Seconds. --->
  • ) />
  •  
  • </cfif>
  •  
  •  
  • <!--- Set page settings. --->
  • <cfsetting
  • showdebugoutput="false"
  • />
  •  
  • </cfcomponent>

If I call "index.cfm" with no URL variable, we are setting the SESSION timeout using a direct CreateTimeSpan() call. This works just fine and outputs the SESSION information.

If I call "index.cfm?a", we are setting the SESSION timeout using the known result of our 5-minute CreateTimeSpan() call. CreateTimeSpan( 0, 0, 5, 0 ) returns the value 0.00347222222222. To test this for yourself see what (5 / 60 / 24) comes out to. When I try this methodology, it returns the ColdFusion error:

Element CFID is undefined in SESSION.

Clearly, the session is not working. If I call "index.cfm?b", we are setting an intermediary variable to a CreateTimeSpan() call and then setting the SESSION timeout equal to that variable. My theory here was that maybe indirect settings just would not work. This worked just fine, so it had nothing to do with where the CreateTimeSpan() was applied.

If I call "index.cfm?c", I set an intermediary variable to our known time span value, just to see if maybe directly setting the known value was breaking. This returns the same ColdFusion error as above.

I realized at this point, that it had nothing to do with directly or intermediary setting. It must have been something to do with the value returned by CreateTimeSpan() that was some how getting lost in translation to the known value. I decided that it was time to see what class of data we were even dealing with:

 Launch code in new window » Download code as text file »

  • #CreateTimeSpan( 0, 0, 5, 0 ).GetClass().GetName()#

... returns:

java.lang.Double

Ahhhhh! We are NOT dealing with just any old number. We are dealing with a Java Double. So, now, when I call "index.cfm?d", I set the intermediary value to the JavaCast-Double value of the known time span value. This works like a charm. This could be done without an intermediary variable as well.

That is very subtle. Very subtle indeed. I think the ColdFusion error is not helpful in this case. It's some sort of casting issue. When I put the known value of the time span directly in the code, ColdFusion sees this as String value. Then, it has to cast that to a numeric value for use with the SessionTimeout value. When casting from string, it must NOT cast to a double by default and then the value is not coming through.

This seems like a bug to me. But, then again, ColdFusion is typeless... how can I hold it accountable for not knowing which type of number to cast to.

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Permalink  |  Other Searches  |  Print Page



Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

Jul 30, 2007 at 1:45 PM // reply »
8 Comments

Nice work Ben.
Please post the final code you use instead of createTimeSpan now.


Jul 30, 2007 at 2:24 PM // reply »
6,516 Comments

@Topper,

I actually still use the CreateTimeSpan(). It just seemed easier than trying to come up with a work-around. And, if I was gonna go with JavaCast(), I might as well just go with CreateTimeSpan().


Jul 30, 2007 at 6:36 PM // reply »
8 Comments

Makes sense. Thanks Ben.


Aug 22, 2007 at 4:44 PM // reply »
1 Comments

Found this little gem of information, i was tearing my hair out converting my application.cfm to application.cfc for the first time, getting session errors left and right.

In all my old application.cfm files, specifically the cfapplication tag, using sessiontimeout="0.02084" (30 minutes) works like a charm.


Dec 29, 2007 at 2:17 PM // reply »
1 Comments

Thanks


Dec 5, 2008 at 3:38 PM // reply »
2 Comments

Interesting,

Well I have been trying to prevent my browser functionality from being functional. What I mean by that is when I cflogout, sessiontimeout="#CreateTimeSpan(0,0,0,0)#" in my logout file everything works just fine except I want my browser controls to stop being functional. How can I prevent the browser buttons from being functional is what I have been trying to achieve.

After selecting the logout link, you are sent to the default page for the site. After attempting to select a page that requires a login the login form appears just as it should. Remind you I am still using a Application.cfm file for my application file.

It seems that the site session ends, but the actual browse sesion does not end.

Can someone help me with this issue?

Kindest Regards,

Ty Whalin


Dec 5, 2008 at 4:15 PM // reply »
6,516 Comments

@Ty,

I am not sure what you mean? You want to disable the back/forward controls on the browser?


Dec 6, 2008 at 12:02 AM // reply »
1 Comments

Yes, that is correct/what I mean. How can it be truely logged out when the browser buttons still allow me to return to the page that I logged out from? Sure, I completely understand if I close the browser the session expires. First, I'm using a Access DB at the moment for my Clientmanagement, there are three different Application.cfm files, one for the entry of the site, the next for the secure area of the site, and third one for the logout page.

Next, between the time I wrote the original message to you, I had to restructure my navigaional links on my main menu because I noticed the spry assests were causing several problems concerning login and logout. My only means of entering the site now are via the Account link on my main menu. It goes directly to the LoginForm.cfm. After a successful login all pages are using the getAuthUser() code. When selecting the logout link provided on the main menu, the logout.cfm sends me back to my default page when you first enter the site.

But of course the problem still persist when using the browser buttons. The actual getAuthUser() displays the UserLogin name, which is defined in the cfloginuser tag. Shouldn't the getAuthUser() no longer be valid if the cflogout tag is called in the logout.cfm? It seems to me that CreateTimeSpan(0,0,0,0) should end the session and the getAuthUser() should no longer be valid.

I also placed a cflogout tag on all the pages that do not need to be securely logged in. Finally, the original question; I believe that if the sessiontimeout is set to CreateTimeSpan(0,0,0,0) and the cflogout tag is included, then the browser buttons should be disabled. The only other reason I would say, is my session is not actually loging out of the session, which is probably the case.

All help is greatly appreciated,

Neo Symmetry
P.O. BOX 453
Ocklawaha, FL. 32183

(352) 505-2968

Ty Whalin


Dec 6, 2008 at 9:59 PM // reply »
6,516 Comments

@Ty,

It sounds like you just have a caching issue in the browser. I am sure that if the user actually tried to click on any of the links, the server wouldn't let them. Browser caching is a tough thing to deal with. I don't have a great suggestion for this.


Post Comment  |  Ask Ben

Recent Blog Comments
Nov 21, 2009 at 6:47 PM
Hal Helms - Real World Object Oriented Development, Sarasota - Day Five
@charlie griefer, Thank you.. ... read »
Nov 21, 2009 at 5:15 PM
Using ColdFusion Structures To Remove Duplicate List Values
@Jose Galdamez, Oh heh yeah I didn't paste the whole code. I should have defined the vars -- my bad. It's fixed thou. Thanks. ... read »
Nov 21, 2009 at 4:49 PM
Styling The ColdFusion 8 WriteToBrowser CFImage Output
Great work yet again Ben! Whilst I didn't use this whole code, I copied some of your regex code for a similar problem with the lack of an alt attribute and unescaped ampersands in CFIMAGE for Railo 3 ... read »
Nov 21, 2009 at 1:13 PM
My First ColdFusion Builder Extension - Encrypting And Decrypting CFM / CFC Files
@Ben, Because I am pedantic, I just want to make sure that everyone knows there is absolutely no encryption going on. There is only encoding and obfuscation. The cfencode tool only obfuscates your C ... read »
Nov 21, 2009 at 12:28 PM
Using ColdFusion Structures To Remove Duplicate List Values
@Jody I can't seem to get your code sample to work. If you are still having problems, try this code out and see if it gets you what you wanted. <!--- Comma delimited list with various duplicates ... read »
Nov 21, 2009 at 11:03 AM
Groovy Operator Overloading Does Not Work In The ColdFusion Context
Hi Ben, Thanks for this informative post. Now I am reading ur old posts too ... read »
Nov 21, 2009 at 10:56 AM
HostMySite.com Has The Best ColdFusion Hosting
@Mehul, Yes very nice people, however several downtimes per day which was not acceptable. Hence we had to move out. I am glad you are having good luck with them so far. ... read »