Skip navigation
Currently Being Moderated

Terminating a session

Nov 24, 2011 3:33 PM

I remember reading an article that terminating a session was not as simple as you would hope and that often happened were that the session variables were removed but the session was still active.

 

I have this <cfset tempvariable = StructClear(session)> to clear the session, but I want to make sure that the session is completely and utterly terminated.

 

I have to create a session when a user visits my script, but then depending on what country they are in I may immediately terminate the session and no content will be served to them, so the last thing I need are a huge amount of dead sessoins hanging around.

 

Could anybody confirm the best way to do this

 

Thanks

 

Mark

 
Replies
  • Dave Watts
    747 posts
    Mar 11, 2003
    Currently Being Moderated
    Nov 24, 2011 4:22 PM   in reply to ACS LLC

    Typically, you do delete session variables but leave the session active. If you don't want a huge amount of dead sessions hanging around, keep the session timeout short. I don't think I'd worry about it beyond that, until you run into an actual problem.

     

    Dave Watts, CTO, Fig Leaf Software

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 25, 2011 2:38 AM   in reply to ACS LLC

    ACS LLC wrote:

     

    I remember reading an article that terminating a session was not as simple as you would hope and that often happened were that the session variables were removed but the session was still active.

     

    I have this <cfset tempvariable = StructClear(session)> to clear the session, but I want to make sure that the session is completely and utterly terminated.

     

    I have to create a session when a user visits my script, but then depending on what country they are in I may immediately terminate the session and no content will be served to them, so the last thing I need are a huge amount of dead sessoins hanging around.

     

    Could anybody confirm the best way to do this

    Terminating a session is indeed a far from simple matter. (I am assuming you are using ColdFusion session management). Commonly, ColdFusion terminates a session if the session has remained idle during the period given by the sessionTimeout. ColdFusion has been designed to handle millions and millions of sessions in memory, which is why using structClear(session) is usually frowned upon. There is really no need to use it!

     

    StructClear(session) instructs ColdFusion to delete not only user-defined variables like session.myVar, but also the system variables session.sessionID, session.CFID and session.CFToken. However, if the session had not timed out and the user continued to navigate beyond this page, which is often the case, ColdFusion would continue to maintain the session until the browser closed.

     

    The usual advice is to use structDelete, and to remove just the user-defined session variables. The only drawback is when your application has many user-defined session variables. It would then be tedious to remove them all, one by one.

     

    There is however a solution for that. Define one struct, and store all your session variables in it, thus

     

    <cfset session.myData = structNew()>

    <cfset session.myData.myVar001 = "...">

    ...

    <cfset session.myData.myVar100 = "...">

     

    To clear the session data later, it will be sufficient for you to do something like

     

    <cfset session.isUserSessionDeleted = structDelete(session,"myData")>

     
    |
    Mark as:
  • Dave Watts
    747 posts
    Mar 11, 2003
    Currently Being Moderated
    Nov 25, 2011 2:37 PM   in reply to Dan Bracuk

    Read this:

    http://www.bennadel.com/blog/1131-Ask-Ben-Ending-ColdFusion-Session-Wh en-User-Closes-Browser.htm

     

    This doesn't actually end the session, though - it just disconnects the user's browser from the session, which will remain on the server until it times out. That said, that's all I usually do, but if you were primarily concerned with the buildup of unused session data this wouldn't alleviate that problem.

     

    Dave Watts, CTO, Fig Leaf Software

     
    |
    Mark as:
  • Dave Watts
    747 posts
    Mar 11, 2003
    Currently Being Moderated
    Nov 25, 2011 2:40 PM   in reply to BKBK

    The usual advice is to use structDelete, and to remove just the user-defined session variables. The only drawback is when your application has many user-defined session variables. It would then be tedious to remove them all, one by one.

     

    There is however a solution for that. Define one struct, and store all your session variables in it ...

     

    While this is the approach I generally follow, it isn't really that tedious to remove a bunch of individual session variables, since you can simply loop through the scope in a few lines of code.

     

    Dave Watts, CTO, Fig Leaf Software

     
    |
    Mark as:
  • Dave Watts
    747 posts
    Mar 11, 2003
    Currently Being Moderated
    Nov 25, 2011 3:03 PM   in reply to ACS LLC

    Well, I'd recommend against going down that path if you can help it. Instead, consider setting a shorter timeout - the default is twenty minutes. If you reduce this to ten or even five minutes, you probably won't have any problems. The ultimate underlying problem is that you have no absolutely guaranteed way to know that a user has finished her session. You can build logout mechanisms, and if a user logs out you could take that to indicate the end of the session, but unless the user gives you some positive cue like this you simply don't have a way to know the user's intent.

     

    In general, I'd recommend avoiding things that seem like premature optimization.

     

    How do you define the user defined sessions? Sessions I set in the code?

     

    I don't think anyone here means "user-defined sessions". What's meant by "user-defined" here is the variables that are created by you rather than by CF (Session.CFID, Session.CFTOKEN, etc).

     

    Dave Watts, CTO, Fig Leaf Software

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 26, 2011 6:29 AM   in reply to ACS LLC

    ACS LLC wrote:

     

    How do you define the user defined sessions? Sessions I set in the code?

    Yes. I chose to call session variables like session.myVar, session.ACS_LLC_Var, and so on, user-defined. Whereas I would call the variables session.CFID, session.CFToken, session.URLToken and session.sessionID system-defined

     

    ACS LLC wrote:

     

    This is getting complicated ;-)

     

    I did just re-write my code so that I don't establish a session if the user is not in the right country, so that will be a huge help, however I'd still like to kill off anybody that has finished their session, rather than have it hang around.

     

    ColdFusion can handle millions of session variables in memory, no sweat. In fact, the engine has been optimized for extreme efficiency in handling the system-defined session variables. So you shouldn't worry about people hanging around. As a matter of fact, it is usually good design to have sessions hanging around. I'll illustrate with a use case.

     

    Imagine you have a major shop. You have a sale. To make it even more irresistible, you had run an advertising campaign in the previous weeks, in which you issued a limited number of 75% cut-price one-day vouchers to lucky customers. The sale is today, big-bang Saturday.

     

    It is naturally hectic on the day, as you had expected. You had in anticipation set up the usual first-come-first-served ticketing system at the checkout counter, to help you manage the large numbers.

     

    The customers who have obtained a checkout ticket (and are now in a checkout queue) could be compared to the visitors of a website. The ticket corresponds to a system-defined session variable, for example, session.sessionID. The voucher, which only the lucky few have, corresponds to a user-defined session variable.

     

    Would you only allow voucher holders to proceed to checkout or give preference to voucher holders in the queue? No. That would be unfair and even impracticable.

     

    You would want customers to proceed to checkout on a first-come-first-served basis, irrespective of whether they have a voucher or not. Customers themselves would expect that as well. So, too, you should allow the visitors of your website to keep their session.CFID, session.CFToken and session.sessionID, irrespective of whether they are in the right country or not. If a visitor wishes to further explore your site after he finishes doing business with you, then it will be impracticable to hinder him.

     

    Would your shop collect vouchers when the customer checks out? Naturally. Otherwise, customers will just turn round and reuse them. However, it is to your advantage that customers continue shopping even without a voucher.

     

    Likewise, when the website visitor has finished his session, it is sufficient for you to delete the user-defined session variables that were created during his session (for example, session.username, session.country, session.email, and so on). Again, you should allow him to keep his session.CFID, session.CFToken and session.sessionID. It is to your advantage that he decides to stay on to explore your site.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 27, 2011 1:44 AM   in reply to ACS LLC

    ACS LLC wrote:

     

    Thanks for the in-depth reply. This is actually not technically a web site, it's an offer path for advertisers, presented inside a mobile phone app, so it looks like an app even though it's web based. We can only serve offers to certain countries, and the ones not in the list have no value and we don't want to show them anything, literally nothing, so any resources given to that user are a complete waste, which is why I recoded it to abort the code immediately before the session was created.

     

    Once a user has completed the 'path' they are done, I don't need the session, so just trying to make sure my code is as tight as it can be without going crazy.

     

    I think I'll just drop the session time out down to 15 minutes and then also structdelete the user defined variables and leave it at that.

     

    I can see why you would want to completely kill sessions in this case. 

     

    You'd think that CF would have a kill that session completely command

    It has something close to that. In fact, that is what I would recommend for you: use J2EE session management instead of ColdFusion session management. You can then invalidate sessions by means of

     

    <cfset getPageContext().getSession().invalidate()>

     
    |
    Mark as:
  • Dave Watts
    747 posts
    Mar 11, 2003
    Currently Being Moderated
    Nov 28, 2011 7:24 AM   in reply to ACS LLC

    J2EE sessions use a single cookie, JSESSIONID, instead of two cookies, CFID and CFTOKEN. The JSESSION cookie is a session cookie - that is, it's automatically destroyed when the browser is closed. J2EE sessions can be integrated with J2EE applications other than CF, and can be managed by the same Java code you'd use in a Java J2EE application. I generally recommend the use of J2EE sessions in CF applications, if for no other reason than the cookie is deleted when the browser is closed.

     

    All that said, I wouldn't bother explicitly killing the sessions unless you actually encounter a problem with not killing them. You're trying to solve a problem that may not exist, and the solution may end up having unintended consequences. What happens if the mobile phone app refreshes a page after you've invalidated the session? My recommendation is just to keep the session timeout very short, and let the server take care of everything for you.

     

    Dave Watts, CTO, Fig Leaf Software

     
    |
    Mark as:
  • Dave Watts
    747 posts
    Mar 11, 2003
    Currently Being Moderated
    Nov 28, 2011 8:53 AM   in reply to ACS LLC

    Yes, you could just delete the part that makes CF's cookies into "session" cookies. You wouldn't even have to look for JSESSIONID specifically - you could continue to look for session.aff as you're doing now.

     

    Dave Watts, CTO, Fig Leaf Software

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 28, 2011 9:01 AM   in reply to ACS LLC

    ACS LLC wrote:

     

    Ahh I see.

     

    This is what I'm using right now. I guess I can dumpe the structkey part, and just have a CFIF at the bottom just look for the JSESSIONID, as long as that exists all my other session variables should be there:

     

     

    <cfapplication

        sessionmanagement="yes"

        name="myapp"

        sessionTimeout="#createTimeSpan(0, 0, 20, 0)#"

            />

     

    <!---// make sure cookies expire when the user closes their browser //--->

    <cfif structKeyExists(cookie, "cfid") and structKeyExists(cookie, "cftoken")>

        <cfset localCFID = cookie.cfid />

        <cfset localCFTOKEN = cookie.cftoken />

        <!---// reset the cookies //--->

        <cfcookie name="CFID" value="#localCFID#" />

        <cfcookie name="CFTOKEN" value="#localCFTOKEN#" />

    </cfif>

    Forget about jsessionID. You are now using the alternative, ColdFusion session management, which is OK. Just one suggestion:

     

    <cfif structKeyExists(cookie, "cfid")>

        <cfset localCFID = cookie.cfid />

        <!---// reset the cfid cookie //--->

        <cfcookie name="CFID" value="#localCFID#" />

    </cfif>

    <cfif structKeyExists(cookie, "cftoken")>

        <cfset localCFTOKEN = cookie.cftoken />

        <!---// reset the cftoken cookie //--->

        <cfcookie name="CFTOKEN" value="#localCFTOKEN#" />

    </cfif>

     
    |
    Mark as:
  • Dave Watts
    747 posts
    Mar 11, 2003
    Currently Being Moderated
    Nov 28, 2011 10:18 AM   in reply to ACS LLC

    The negative is that you don't absolutely know when the browser is closed, and you don't know what exactly happens when you invalidate a session. In other words, you don't know that it will actually improve performance or memory management in any way w/r/t your application.

     

    Dave Watts, CTO, Fig Leaf Software

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points