7 Replies Latest reply on Nov 5, 2010 10:21 AM by ilssac

    Block concurrent  logins

    n_kip

      Hi, I'm trying to block concurrent logins.

       

      What I've done so far:

       

      I've added a new column in the login table called logged, which holds values 1 or 0

      When a user logs in, it updates the value to 1.

      It will login user's who's status is 0.

      When users click logout, it changes the status to 0

       

      The Problem

       

      If the user just closes the browser, how is the system supposed to know that the user's logged status needs to be 0?

      I reasoned that the onSessionEnd method would do the trick. When the session expires, it simply updates the database for that user to 0. So I put in the code, but nothing.

       

      <cffunction name="onSessionEnd" returnType="void">
          <cfquery name="updateloggedstatus" datasource="datadsn">
                      UPDATE usermanagerlogin
                      SET logged = <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="0">
                      WHERE userid = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="user1">
          </cfquery>       
      </cffunction>

       

      In another application, I have used the onSessionEnd method succesully. I have used it to delete the items that were in the shopping cart, which were in the database, who's order was not complete.

       

      <cffunction name="onSessionEnd" returnType="void">

       

          <cfargument name="SessionScope" required=True/>
         
      <cfquery name="deletesessionendticket" datasource="tickdsn">
          DELETE FROM tbltick

         WHERE oid = '#Arguments.SessionScope.oid#'
          AND ordered = <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="0">
      </cfquery>

       

      </cffunction>

       

      The difference between the two is that the new app is being developed in cf9, while the older app was built in cf8

       

      In the current app, the session does end succesfully, in that it asks me to login, but the onSessionEnd method is not executed.

       

      Any Ideas?

       

      Much appreciated.

        • 1. Re: Block concurrent  logins
          Dave Watts Adobe Community Professional

          There's no mechanism built into HTTP to track what happens when the user closes his browser. In other words, the server doesn't know when the user closes his browser. All the server knows is that the user hasn't made another page request.

           

          If no page request is received before the timeout, the session ends. The onSessionEnd function will only be invoked when the timeout has occurred. If the user closes his browser, the cookie associating that user's browser with the session is destroyed (assuming it's a session cookie) but the session exists until the timeout.

           

          None of that really addresses your underlying question, which is how to prevent concurrent logins but not block users when their sessions haven't expired yet. There aren't really any great answers for this, in my opinion. You could track users' IP addresses, or use JavaScript to send events back to the server. Neither of those options are foolproof, though.

           

          Dave Watts, CTO, Fig Leaf Software

          http://www.figleaf.com/

          http://training.figleaf.com/

           

          Fig Leaf Software is a Veteran-Owned Small Business (VOSB) on

          GSA Schedule, and provides the highest caliber vendor-authorized

          instruction at our training centers, online, or onsite.

           

          Read this before you post:

          http://forums.adobe.com/thread/607238

          • 2. Re: Block concurrent  logins
            Dan Bracuk Level 5

            By concurrent logins do you mean the same user logging in more than once or having more than one person logged in at once?  Also, what problems are you trying to solve or prevent by doing this?

            • 3. Re: Block concurrent  logins
              n_kip Level 1

              Thanks for your response.

              Just need to have this straight. So there is no by-the-book method of doing this? If so, does this mean that we have to do cowboy coding?

              • 4. Re: Block concurrent  logins
                Dave Watts Adobe Community Professional

                I'm not sure what you mean by "cowboy coding", but there's nothing built into HTTP to signal the end of a session from the browser. As Dan mentioned, it might be useful to describe exactly what you're trying to prevent.

                 

                Dave Watts, CTO, Fig Leaf Software

                http://www.figleaf.com/

                http://training.figleaf.com/

                 

                Fig Leaf Software is a Veteran-Owned Small Business (VOSB) on

                GSA Schedule, and provides the highest caliber vendor-authorized

                instruction at our training centers, online, or onsite.

                 

                Read this before you post:

                http://forums.adobe.com/thread/607238

                • 5. Re: Block concurrent  logins
                  ilssac Level 5

                  n_kip wrote:

                   

                  Thanks for your response.

                  Just need to have this straight. So there is no by-the-book method of doing this? If so, does this mean that we have to do cowboy coding?

                   

                  Not sure why you would need to get a cowboy to do this for you.  But yes you are fighting the current HTTP standards which declare that all requests are completely separate and completely unrelated to any requests that come before or after this request.

                   

                  But there are several ways that you can work to prevent some of this behavior, just know that none of them are perfect they all have the problems of false negatives (i.e. some people who break the rules will not get caught) and false positives (some people are who are NOT breaking the rules will get kicked off)

                   

                  But there are ideas that might help using some combination of cookies, javascript, IP addresses, session state, etc.

                  • 6. Re: Block concurrent  logins
                    n_kip Level 1

                    Thank you for your response,

                    concurrent logins meaning the same account not being able to login from different computers at the same time.

                     

                    What I have done is I have tried to have the status for the logged in user to be updated to "1" just when the user logs in, and then update the status to "0" when the user logs out. When some one tries to use the same account from another location, and the status for that account is "1", that user would not be logged in.

                    So far all has worked, except with the onSessionEnd.

                     

                    When the user clicks on logout, the status is changed to "0", but what happens if the user closes the browser without clicking of logout? The status will remain on "1", and users will not be able to login when they try to login. That is why I chose to use the onSessionEnd method. I expect the code inside it to execute when the session times out, but it is not executing the code.

                     

                    Any contribution is welcomed,

                    Nich

                    • 7. Re: Block concurrent  logins
                      ilssac Level 5

                      n_kip wrote:

                       

                      What I have done is I have tried to have the status for the logged in user to be updated to "1" just when the user logs in, and then update the status to "0" when the user logs out. When some one tries to use the same account from another location, and the status for that account is "1", that user would not be logged in.

                       

                      I would strongly suggest you go the other way.  Instead of not allowing the current logon, end the previous login state.  Otherwise you are dooming people who may have logged in on a computer that they no longer have access to from being able to use another computer.  For example, somebody logs on at work, goes home and can not logon from there because they are logged on at work.

                       

                      What are you tryting to do in the OnSessionEnd event?  HOW is it not working?

                       

                      P.S.

                      Have you ever noticed the important differences between these two WHERE clauses?

                      n_kip wrote:


                      WHERE userid = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="user1">


                      WHERE oid = '#Arguments.SessionScope.oid#'

                       

                      The first one is using a string litteral "user1", the second one is using a variable "#Arguments.SessionScope.oid#".  Also the first one would be using an unscoped variable if changed to "#user1#" while the second one is using a variable in the 'SessionScope" structure that is passed into the "Arguments" scope when the session end event fires.

                       

                      It is important to remember that when the session event fires there are several variable scopes that no longer exists, most critically the session scope itself.  The session has ended, the scope is no longer valid.  Thus what was in the scope is passed into the function's argument so the data can be used within the event handler.

                       

                      P.P.S.

                      I just wanted to reiterate from your original post that the onSessionEnd event has little to nothing to do with when a user closes a browser.  Your browser does not go back to all the web sites you have visited and tell each and every one "Kip has closed me", and you would probably not want it to do so.  All the servers can do is wait and wait and wait, and if it receives no new requests containing known identification data of an existing session in a given time frame then end the session.  This is when the session end event will fire and the onSessionEnd handler be executed.

                       

                      You CAN configure that the identification data -- (CFID and CFTOKEN) or JSESSIONID -- normally stored in cookies to be "session cookies" that are only stored in memory by the browser and discarded by the browser when it is closed.  Thus if a user opens a new browser and connects to your server before the previous session has timed out, the browser will not present the previous cookies but rather be presented new ones by the server, thus creating a new session.  And the old one will be left to die when its timeout period expires.