Posted in ColdFusion | Posted on 01-02-2009 | 8,680 views
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.


<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.
<cfset safeList = "sessionid,urltoken,cfid,cftoken">
<cfloop collection="#session#" item="i">
<cfif not ListFindNoCase(safelist,i)>
<cfset structDelete(session,i)>
</cfif>
</cfloop>
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
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.
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...
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.
@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.
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
I've even tried
<script>
structClear(session);
</script>
and get the same error.
What am I doing wrong?
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>
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?
essionid,urltoken,cfide,cftoken
that should be:
essionid,urltoken,cfid,cftoken
It's a frequent slip (our brains typing--or in this case no one else even seeing) CFID and CFIDE as the same. :-)
Indeed, Ray, I suspect some may never see my comment here. Might you want to just edit Scott's comment to correct this? Feel free to delete mine in this case. (Or maybe you'd want to keep it for some reason, with this comment, and another from you saying you changed it.) Your call.
Did you by any chance change the comment from Scott? If so, perhaps you have to refresh the blog, because it's still showing CFIDE. Or were you preferring not to update his comment, hoping instead people will read all the way to the bottom before trying to use it? I fear they would not. :-)
[Add Comment] [Subscribe to Comments]