18 Replies Latest reply: Nov 28, 2011 10:24 AM by ACS LLC RSS

    Terminating a session

    ACS LLC Community Member

      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

        • 1. Re: Terminating a session
          Dave Watts CommunityMVP

          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

          • 3. Re: Terminating a session
            BKBK CommunityMVP

            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")>

            • 4. Re: Terminating a session
              Dave Watts CommunityMVP

              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

              • 5. Re: Terminating a session
                Dave Watts CommunityMVP

                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

                • 6. Re: Terminating a session
                  ACS LLC Community Member

                  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.

                   

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

                  • 7. Re: Terminating a session
                    Dave Watts CommunityMVP

                    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

                    • 8. Re: Terminating a session
                      BKBK CommunityMVP

                      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.

                      • 9. Re: Terminating a session
                        ACS LLC Community Member

                        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. You'd think that CF would have a kill that session completely command

                        • 10. Re: Terminating a session
                          BKBK CommunityMVP

                          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()>

                          • 11. Re: Terminating a session
                            ACS LLC Community Member

                            How does J2EE differ? I switch this over in the CF administrator? Will it effect my code on any of my sites or will they still continue to work the same?

                             

                            I'm not familiar with doing this with J2EE and not sure of the differences

                             

                            Mark

                            • 12. Re: Terminating a session
                              Dave Watts CommunityMVP

                              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

                              • 13. Re: Terminating a session
                                ACS LLC Community Member

                                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>

                                 

                                 

                                <CFIF NOT #IsDefined('session.aff')#>

                                <CFINCLUDE TEMPLATE="defaultvariables.cfm"><CFLOCATION URL="index.cfm"></CFIF>

                                • 14. Re: Terminating a session
                                  Dave Watts CommunityMVP

                                  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

                                  • 15. Re: Terminating a session
                                    BKBK CommunityMVP

                                    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>

                                    • 16. Re: Terminating a session
                                      ACS LLC Community Member

                                      The Jsession sounds like a better idea though, if I am able to terminate the session as soon as the browser is closed, that extra piece of mind, where there is a positive, there always seems to be a negative though, I wonder what it is

                                      • 17. Re: Terminating a session
                                        Dave Watts CommunityMVP

                                        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

                                        • 18. Re: Terminating a session
                                          ACS LLC Community Member

                                          I missed one of your messages.. so very little change, just look for session.aff still , remove the cookie part and it will work.

                                           

                                          What's the benefit of even having the set up that I have right now?

                                           

                                          Because this is working inside a mobile phone and we disable the back button, I am reasonably confident that when the session is ended, it's ended, they can't do anything else, if they come back we can create another session