Posted in ColdFusion | Posted on 01-01-2009 | 7,499 views
Steph has a few questions/concerns about cflogout, sessions, and the back button. His email to me was:
Hi Ray, What's the best practice for logging out users using cflogin and cflogout? I'm using CF7, and I cant figure out how to workaround the following issues listed in livedocs:
Caution: If you use web server-based authentication or any form authentication that uses a Basic HTTP Authorization header, the browser continues to send the authentication information to your application until the user closes the browser, or in some cases, all open browser windows. As a result, after the user logs out and your application uses the cflogout tag, until the browser closes, the cflogin structure in the cflogin tag will contain the logged-out user's UserID and password. If a user logs out and does not close the browser, another user might access pages with the first user's login.
Also....
In many cases, you can effectively end a session by clearing the Session scope, as shown in the following line. The following list, however, includes important limitations and alternatives:
<cfset StructClear(Session)>
Clearing the Session scope does not clear the session ID, and future requests from the browser continue to use the same session ID until the browser exits. It also does not log the user out, even if you use Session scope storage for login information. Always use the cflogout tag to log users out.
Well, I use cflogout, but if you use the back button you are still able to access the protected pages, and session variables are maintained.
What's the best way to completely log a user out (kill session variables, etc) while keeping the browser open?
There's a lot going on there, so let me try to pick it apart. First off, the issue mentioned in the live docs quote above (direct link here) relates to the fact that ColdFusion's CFLOGIN system will automatically connect to any web server level security enabled. My readers know that I've been a bit ticked at CFLOGIN for some time now. I once lost a whole day trying to debug an issue with BlogCFC that ended up being related to this. There is no way to disable CFLOGIN's ties to web server security. That means trouble if you don't want to use it. This is why I do not recommend using CFLOGIN anymore. I still use it in my OS applications but I'm slowly rolling it out. (The last update to Soundings removed it.)
So with that in mind - I'd just stick to simple session variables. That removes any problems with the web server level security. It's no longer an issue. But then that leaves your last issue:
Well, I use cflogout, but if you use the back button you are still able to access the protected pages, and session variables are maintained.
Technically, the session variables weren't maintained. What you are seeing is simply the browser's cache being used to redisplay an old page. The session variables on the server were really cleared.
So how do we stop the pages from being cached? You have to remember that the browser, not you, is the ultimate judge on what it will and will not cache. We can tell the browser to not cache, but that doesn't mean the browser won't ignore your request. The user could also just save the HTML to the desktop. It would be dumb for a user to save a sensitive page of credit card information to their desktop, but I bet we all know a few users who would do that.
With that in mind then, the code to tell the browser to not cache is rather simple, and is described at the ColdFusion Cookbook entry: How can I prevent a browser from caching my page?
2<cfheader name="pragma" value="no-cache">
3<cfheader name="expires" value="#getHttpTimeString(now())#">
Steph, hope this helps!


I have also personally ran into issues with network based caching systems. These do just the same as client software but on a larger scale.
I don't really have a good way around these so sorry for that. I just wanted to bring them up in case someone else might.
--Dave
Something about how structClear will delete the sessionid and cfid and cftoken.
But that was years ago.
Well wait, I stand corrected. :) It removes cfid, cftoken, and sessionid. It looks like structClear is still "naughty". Everything worked fine though with this sample code:
<cfif structKeyExists(url, "clear")>
<cfset structClear(session)>
</cfif>
<cfparam name="session.hits" default="0">
<cfset session.hits++>
<cfdump var="#session#">
I could clear the session and still add values to hits. But if I had written any code to depend on sessionid, it would fail. Oddly, urltoken, one of the 'builtin' session variables, was also nuked on the FIRST hit with clear=1 in the URL, but returned after clear was removed. So CF 'fixed' up one built in var but not the others. Also, the values in URL token matched the CFID/CFTOKEN I had before.
So I'd probably not recommend doing a struct clear on session now.
You mentioned that the session variables are cleared on the server but maintained in the cached page. I logged out and then used the back button until I reach the first page that I accessed after logging in. When I do a shift-refresh of this page, I am then able to proceed to other pages as if I were logged in, and the session variables are still available per the debug info.
I changed my app so that the login page points to a redirect page that points to the first page of the app. This seems to solve the shift-refresh problem.
Are there any plans to fix the cflogin issue with the next CF version?
Steph
You mentioned you were able to shift-refresh on a page. Was that page the result of your login? (You said you went to the first page.) If so, what you see is the browser re-POST-ing the form details from the login, so in essence, you logged in again.
Making your login page do a cflocation does help because then the user can't reload the page to relogin.
This is not broken, Steph. It's just the nature of the web, browsers, and your cache settings.
1. how to force CF to end a session on browser close? the session structClear is working great for me, but sometimes the user just closes it.
2. keeping a session variable consistent between https and http pages. Sometimes CF seems to come up with a new session ID when going from HTTP to HTTPS and back. Undoubtedly, its my misunderstanding of proper usage ... but I figured a jedi might know.
thanks again for all your good work and sharing!
2) That's because, technically, it is a different site. If you are using APplication.cfc, try using setDomainCookies=true. I believe it changes the cookie from foo.main.com to *.main.com. I always forget the exact change so forgive me if that is wrong.
Firefox and IE seem to respect this very well, however, Safari does not. In other words, I can hit the back button in Safari (3.2.2) and still see the previous cached page instead of the app redirecting to the login page (as Firefox and IE do so well).
Has anyone else experienced Safari not obeying cfheader? If so, how did you make Safari take orders?
Phillip, I'm already using that code:
<cfheader name="cache-control" value="no-cache, no-store, must-revalidate" />
<cfheader name="pragma" value="no-cache" />
<cfheader name="expires" value="#getHttpTimeString(now())#" />
I use a really different method when it comes to processing security, I do however use cflogin and cfloginuser but I also create a UUID and log the ip into a database and if the UUID doesn't match the ip I send them to the logout processor. Is that a smart way to process security?
I've pretty much tried the CFHEADER tags on each page.
<cfheader name="cache-control" value="no-cache, no-store, must-revalidate">
<cfheader name="pragma" value="no-cache">
<cfheader name="expires" value="#getHttpTimeString(now())#">
This really helped for Firefox3.0.12 & for Netscape Navigator9.0b3 BUT NOT FOR Opera 9.64 & very importantly NOT FOR Internet Explorer 7.0.6001.18000.
A major concern is that majority of web users use IE!
Please can anyone provide a tried & tested permanent solution please? It'd be really appreciated. Thanks
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="Mon, 07 July 2009 00:00:00 GMT">
Anyone have any thoughts on managing session vars in multi tabs in the same browser window?
In my opinion, this is _not_ a limitation of session vars.
Without a way to identify tabs, IMO the practical use of session vars is greatly compromised.
Any thoughts are appreciated. - Tim
There is one simple solution - if a user is logged in, don't let them log in again. Tell them as much and then provide a link to the logout page.
Yes - only allowing one log in per window session will provide as a solution for the multi tab multi user issue. However there are many more potential situations other than just the log in.
Guess my point is CF developers should consider the potential issues with browser tabs when using session vars... (still wishing tabs could be identified.)
Thanks Ray
I have a form page, an action page and a confirmation page.
I submit the form page...takes me to the action page where I validate the fields...the fields are NOT valid..I place the data & the error message in session and redirect(cflocation) to the form page. In the form page I store the session variables(err message and bad data) in local variables, destroy the session variables and use the local variables thereafter.
Now I correct the values and submit the form again...goes to action page...validates and then redirect to the confirmation page.
Now if I use my browser back from the confirmation page, it takes me to the form page with the validation error message and bad data...I understand that the IE 7 browser is using the cache to get the data..but I tried using cfheader and META tags to avoid pulling from cache...still the browser pulls from cache...this doesnt happen in Firefox
Any thoughts on how this can be resolved?
So normally the cfheader thing should work for IE. Can you share the code you used?
I am using the following code:
<cfheader name="cache-control" value="no-cache, no-store, must-revalidate">
<cfheader name="pragma" value="no-cache">
<cfheader name="expires" value="#getHttpTimeString(now())#">
<META HTTP-EQUIV="expires" CONTENT="-1">
<META HTTP-EQUIV="pragma" CONTENT="no-cache">
<META HTTP-EQUIV="cache-control" CONTENT="no-cache, no-store, must-revalidate">
Also, I am interested to know if there is a specific reason (like its a bad practice..) on why you are against using multiple pages. It will be a learning for me.
Thank you for your time!
In general, I don't use an 'action page' for a form. I use a self posting form. Here is an example I just wrote. It may not work - I didn't actually run it I just did it from scratch:
http://pastebin.com/iC0JUAvm
You can see how the form posts to itself. Code on top does quick verification (the form has one field so its simple). If the form is ok (the one field is ok), then we set a flag to not show the form.
This is just an example though.
I thought I replied already but when I checked the site for a response from you....thats when I realized I didnt even reply to your message...very sorry abt that.
Thank you for your example, I am aware of "posting to the same page" method...
Sorry if I was not clear with my question, I wanted to know why you thought the "posting to same page" method was better than the multiple pages method?...these are facts only experienced people can explain....not the books :)
[Add Comment] [Subscribe to Comments]