In yesterday's blog post about cflogout, sessions, and the back button, there was a passing discussion about the structClear function and sessions. Phillip Senn asked if it was safe to use it on the session scope. It seems like it should be as long as you remember that this will not end the session but simply clear the current values.
In the past, the warnings against structClear used to mention that clearing the session would also cause the "special" session variables: CFID, CFTOKEN, and SESSIONID, to be nuked. You can see that described here in this tech note: ColdFusion 4.5 and the StructClear(Session) Function
I was convinced that this wasn't the case in ColdFusion 6 and higher, but I whipped up a quick test to check first. I first wrote this code:
2 <cfset structClear(session)>
3 </cfif>
4 <cfparam name="session.hits" default="0">
5 <cfset session.hits++>
6 <cfdump var="#session#">
This should increment a session variable named hits. If I add clear=1 to the URL it will clear the entire session. I ran this code a few times and confirmed it worked fine:

I then added clear=1 and got:

So it looks like the special variables are definitely cleared. However, the code had no problem setting hits back to 0 and then adding one to it. But get this - I reloaded without clear=1 in the URL and got:

Notice that urltoken is returned but not cfid, cftoken, or sessionid. Also notice that urltoken is right. It has the same cfid/cftoken values from before. So is my session screwed? It seems not. If I used cfid/cftoken/sessionid in my code though it would certainly fail (unless I parsed apart session.urltoken).
I guess the old advice of clearing just want you need, or putting all your custom stuff into a session struct (session.data) and structClearing that, still holds true.

Comment 1 written by Raymond Camden on 2 January 2009, at 9:05 AM
<cfinvoke component="cfide.adminapi.administrator" method="login" adminPassword="admin">
<cfinvoke component="cfide.adminapi.servermonitoring" method="getActiveSessionCount" cfapplicationname="stest" returnVariable="sc">
<cfoutput>Total session count: #sc#<br/></cfoutput>
<cfinvoke component="cfide.adminapi.servermonitoring" cfapplicationname="stest" method="getActiveSessions" returnVariable="sessions">
<cfdump var="#sessions#">
I noticed that when I cleared, it had no impact on the session information returned (ie, time since last access, age, etc). So it looks like, under the covers, there is nothing wrong with structClear(session). If you don't use cfid/cftoken/sessionid in code itself then it should be safe.
Comment 2 written by Scott P on 2 January 2009, at 11:40 AM
<cfset safeList = "sessionid,urltoken,cfide,cftoken">
<cfloop collection="#session#" item="i">
<cfif not ListFindNoCase(safelist,i)>
<cfset structDelete(session,i)>
</cfif>
</cfloop>
Comment 3 written by Red on 2 January 2009, at 1:02 PM
Basically, I login as user A, logout, login as user B, then I click on user-related parts of the site, and I get User A info. When I refresh the page it displays the correct user. CFID/CFTOKEN don't change as one would expect, rather, it takes few logout/refresh for them to change. Also, I added some debugging code onRequestStart() and it doesn't show every time(especially when it flips to the previously logged in user).
By adding rand() to the end of each user-related link on the site I fixed the problem(well if you can call that a fix).
I've never experienced this before, and I am sure I had to go out my way to break this. I searched around, and I couldn't find anything similar to this problem. I wonder if anyone has seen this before?
Thanks
Comment 4 written by DanaK on 3 January 2009, at 12:06 PM
I think I've torn things apart 100x and never could figure it out. I notice IE 6.x has various builds that were pushed out that would wreak general havok with session id's dropping on page hits etc.
Comment 5 written by Raymond Camden on 3 January 2009, at 8:51 PM
You note that when you refreshed a page it seemed to show the right data - that could just be the browser cache aain. So I'd use the suggestions from this entry: http://www.coldfusionjedi.com/index.cfm/2009/1/1/A...
Comment 6 written by Raymond Camden on 3 January 2009, at 8:52 PM
Comment 7 written by Elliott Sprehn on 4 January 2009, at 4:56 AM
CFID and CFToken are sent in cookies when the session is started and your browser stores them for as long as the Set-Cookie header told it to. CF will only send you a new CFID and CFToken if your session expires or your browser didn't send the cookies (they didn't exist, or they expired).
As Ray said, the issue you're describing, and the fix with a random number, is definitely a browser caching problem.
Comment 8 written by Brian on 5 January 2009, at 11:49 AM
@DanaK: We've seen that behavior when the cluster, er um, cluster-bombed... A user would be coming in through the master IP, but for some inexplicable reason, the affinity to a node never stuck...Which resulted in a new cfid/token with about every couple of hits...happened with predictable regularity on form submissions. And this was browser agnostic.
Comment 9 written by Raymond Camden on 5 January 2009, at 11:50 AM
Comment 10 written by Red on 5 January 2009, at 5:29 PM
Ray, How do I "die" :(, and take my phone number with me, gracefully?
Elliott, I can expire CFID/CFTOKEN cookies on logout?
If I use StructClear() and get rid of CFID/CFTOKEN, at which point will ColdFusion send a new pair of CFID/CFTOKEN?
I do understand that the issue I originally asked about is due to caching, and is NOT related to sessions.
Thx
Comment 11 written by Raymond Camden on 5 January 2009, at 6:30 PM
Comment 12 written by Red on 5 January 2009, at 8:12 PM
Comment 13 written by Don on 8 January 2009, at 4:18 PM
I've even tried
<script>
structClear(session);
</script>
and get the same error.
What am I doing wrong?
Comment 14 written by Raymond Camden on 9 January 2009, at 12:38 PM
Comment 15 written by Don on 9 January 2009, at 1:19 PM
I've run into this everytime I've tried to do it. Really strange. Different servers too.
The one I'm doing now has this in the application.cfc file.
<cfif ISDEFINED("url.reset") and url.reset is "DOIT">
<cfset #structClear(session)#>
<cflocation url="index.cfm">
</cfif>
Comment 16 written by Raymond Camden on 10 January 2009, at 8:04 AM
Comment 17 written by Henry Ho on 13 March 2009, at 5:53 PM
http://livedocs.adobe.com/coldfusion/8/htmldocs/he...
"Do not call this function on a session variable. For more information, see TechNote 14143..."
which is,
ColdFusion 4.5 and the StructClear(Session) Function
http://www.adobe.com/go/tn_17479
The last workaround looks interesting. Kill the app? Wouldn't all active Session's be killed?
[Add Comment] [Subscribe to Comments]