18 Replies Latest reply on Aug 10, 2009 10:56 PM by BKBK

    onSessionStart method runs on every request!??

    sean69 Level 1

      having some difficulty with a remote server running the onSessionStart method on every request. Note: this works perfectly in development.

       

      I have this in my application cfc - note where I am dumping the session variable to screen for debugging. what I have noticed is that the onSessionStart method runs every time, resetting the users login [user can;t log in] it used to give a new session id every request, now that has stopped, but no closer to a solution:

       

          <!--- session handling --->
          <cffunction name="onSessionStart" output="true" access="public" >
          
              <cflock scope="session" timeout="5" type="Exclusive">
                  <cfscript>
                      Session.starttime = now();
                      session.authenticated = "false";
                      session.authattempts = 0;
                      Session.shoppingCart = ArrayNew(2);
                  </cfscript>
              </cflock>    
              Session start<cfdump var="#session#" /><br />    
          </cffunction>
          
          <cffunction name="onSessionEnd" output="false" access="public" >
          Session end<cfdump var="#session#" /><br />
          </cffunction>
             
          <!---  request handling --->
          <cffunction name="onRequestStart" output="true" access="public" >
          
              <cfargument name="requestname" required=true/>
              request start<cfdump var="#session#" /><br />
              <cfparam name="message" default="" />
              <cfparam name="success" default="" />
              <cfparam name="error" default="" />
              
              <cfif session.authenticated is not session.sessionid >
                  <cfinclude template="./login.cfm" />
              </cfif>
      
          </cffunction>
          
          <cffunction name="onRequest" output="yes" >
              <cfargument name="targetPage" type="String" required="true" />        
                  the request<cfdump var="#session#" /> <br />
                  <cfif session.authenticated is session.sessionid>
                  
                  <cfscript>
                  if (IsDefined("url.delFromCart")){
                      cart_obj = CreateObject("component", "cfc.cart");
                      cart_obj.delFromCart(url.delFromCart);
                  }
                  </cfscript>
                  
                  <cfsavecontent variable="myContent">
                      <cfinclude template="..#arguments.targetPage#" />
                  </cfsavecontent>
                  
                  <cfoutput>#myContent#</cfoutput>
                  </cfif>
              
          </cffunction>
          
          <cffunction name="onRequestEnd" output="yes" access="public" >
              request end<cfdump var="#session#" /> <br />
          </cffunction>
      
      
      

       

       

       

      Has anyone seen this? must be a server error right?

       

      HELP!!

       

      -sean

        • 1. Re: onSessionStart method runs on every request!??
          Dan Bracuk Level 5

          This looks like a problem in onRequestStart:

              <cfif session.authenticated is not session.sessionid >
                      <cfinclude template="./login.cfm" />
                  </cfif>

          At what point do you attempt to make those two variables equal to each other?

          • 2. Re: onSessionStart method runs on every request!??
            sean69 Level 1

            works perfectly in development environment...

             

            I set the session in the authentication function and just keep checking that [as you can see]

             

            <cflock scope="session" timeout="5" type="Exclusive">
                        <cfscript>
                            session.authenticated = "#session.sessionid#";
                            session.role = "#authenticate.role#";
                            session.gid = "#authenticate.id#";
                        </cfscript>
            </cflock>
            <cflocation url="./index.cfm" addtoken="no" />
            

             

            so that way I have all their roles/creds handy in the session scope, they get checked on every request and to bounce them I check another variable in the request to look for a logout.

             

            -sean

            • 3. Re: onSessionStart method runs on every request!??
              Dan Bracuk Level 5

              If the if/else logic runs at onRequestStart, at what point does your authentication function have a chance to run?

              • 4. Re: onSessionStart method runs on every request!??
                BKBK Adobe Community Professional & MVP
                having some difficulty with a remote server running the onSessionStart
                method on every request. Note: this works perfectly in development.

                 

                The commonest cause of this kind of cross-server discrepancy is that the application and session settings  in the Administrator are not the same. Have you enabled the use of application and session variables in the Administrator? Does your Application.cfc define the usual variables, this.sessionManagement = "true", this.sessionTimeout = "#createTimeSpan(0,0,20,0)#", this.loginStorage = "session",  this.setClientCookies = "true" and so on?

                 

                I expected to see the code for cflogin in onRequestStart. That is where you would do the login validation and set session.authenticated accordingly. I have to assume you have an equivalent construction to do that elsewhere. But I doubt it would  do as good a job as running cflogin in onRequestStart. On a different note, there is no need for a session lock in onSessionStart.

                • 5. Re: onSessionStart method runs on every request!??the
                  sean69 Level 1

                  the login template calls it.

                   

                  <cfparam name="form.username" default="" />
                  <cfparam name="form.password" default="" />

                   

                  <cfscript>
                      if(username is not "" and password is not ""){

                          //validate & sanitize
                          checkuser = application.fnctn.checkinput(username,"all");
                          checkpass = application.fnctn.checkinput(password,"all");
                          if(checkuser gte 1 or checkpass gte 1){
                              //log an error, alert someone !!!
                              application.fnctn.injectionattempt();
                              error = "Sorry, your credentials were incorrect. Please try again.";
                              }else{
                              mylogin = application.auth.login(username,password);       
                              if (mylogin neq 1){
                                  error = "Sorry, your credentials were incorrect. Please try again.";
                                  }else{
                                      //start a session   
                                      application.auth.setupsession(username,password);
                                      }
                              }
                          }
                  </cfscript>

                  • 6. Re: onSessionStart method runs on every request!??
                    sean69 Level 1

                    I've check [and double-triple checked!!] all of this and it all appears correct:

                     

                    Have you enabled the use of application and session variables in the Administrator? Does your Application.cfc define the usual variables, this.sessionManagement = "true", this.sessionTimeout = "#createTimeSpan(0,0,20,0)#", this.loginStorage = "session", this.setClientCookies = "true" and so on?

                     

                     

                    I expected to see the code for cflogin in onRequestStart. That is where you would do the login validation and set session.authenticated accordingly. I have to assume you have an equivalent construction to do that elsewhere.But I doubt it would  do as good a job as running cflogin in onRequestStart.

                    I have never used cflogin, always been developing on linux,  it seems to me that somewhere areound version 4 there was a problem with cflogin+linux, honestly I don't remember, I just started crafting my own authentication and never looked back!

                     

                    However:

                    On a different note, there is no need for a session lock in onSessionStart.

                    ha! yes... I suppose that does make perfect sense.

                     

                     

                    Now,

                    I can't prove this, but It seems that if I set the session.timeout in my application.cfc to exactly the same timeout as in cfadmin, my onSessionStart methods will run on every request.  i.e. I can't get it to fail reliably [!?] by setting different timeout values.

                    As a stopgap, right now I have the application session timeout set to one minute less than the cfadmin timeout. and it seems to be working for a couple of days now, but I am not convinced that the problem will not resurface. I think somehting odd is still going on.

                     

                    -sean

                    • 7. Re: onSessionStart method runs on every request!??the
                      BKBK Adobe Community Professional & MVP

                      <cfscript>
                          if(username is not "" and password is not ""){

                              //validate & sanitize
                              checkuser = application.fnctn.checkinput(username,"all");
                              checkpass = application.fnctn.checkinput(password,"all");
                              if(checkuser gte 1 or checkpass gte 1){
                                  //log an error, alert someone !!!
                                  application.fnctn.injectionattempt();
                                  error = "Sorry, your credentials were incorrect. Please try again.";
                                  }else{
                                  mylogin = application.auth.login(username,password);       
                                  if (mylogin neq 1){
                                      error = "Sorry, your credentials were incorrect. Please try again.";
                                      }else{
                                          //start a session   
                                          application.auth.setupsession(username,password);
                                          }
                                  }
                              }
                      </cfscript>

                       

                      This design is faulty. Application scope means one user sets the variable for the whole application. Therefore, in your current code, all users are using the same login credentials. To correct it, you have to replace every occurrence of application with session.

                      • 8. Re: onSessionStart method runs on every request!??the
                        sean69 Level 1

                        hmmm...  no they are not. the fnctn & auth are objects defined in the application scope.

                        • 9. Re: onSessionStart method runs on every request!??the
                          Dan Bracuk Level 5

                          Your if/else logic in onRequestStart runs before any of that code.

                          • 10. Re: onSessionStart method runs on every request!??the
                            Dan Bracuk Level 5

                            And BKBK was correct when he told you why that's a bad idea.

                            • 11. Re: onSessionStart method runs on every request!??the
                              sean69 Level 1

                              ok - yes, the if/else onRequestStart runs and calls that code. via the login template

                              the fnctn & auth components are stored as objects in the application scope - the username & password vars are local passed from a form...

                              fnctn & auth don't change either - just handy in this case to have persistent objects I assumed that placing static components in the application scope would be more efficient [use storage and memory once rather than for each session] - in fact I started another thread/discussion to that effect, the outcome was I think "who knows"

                               

                              I'm afraid I don't see your points, placing the fnctn & auth components in the session or application scopes seems to me to make no real difference since neither component actually does anything unless specifically requested.

                               

                              as to application scope is to be set by one user - yes...  that's what I was after, one user sets up all the functions & Auth methods.

                               

                               

                               

                              -sean

                              • 12. Re: onSessionStart method runs on every request!??the
                                BKBK Adobe Community Professional & MVP

                                fnctn & auth don't change either - just handy in this case to have persistent objects I assumed that placing static components in the application scope would be more efficient [use storage and memory once rather than for each session]...

                                 

                                I'm afraid I don't see your points, placing the fnctn & auth components in the session or application scopes seems to me to make no real difference since neither component actually does anything unless specifically requested.

                                 

                                as to application scope is to be set by one user - yes...  that's what I was after, one user sets up all the functions & Auth methods

                                 

                                It's false economy in my opinion. One implication of placing the authentication objects in application scope is that  10 000 users currently on your site may have to wait in a queue to log in, one after the other!

                                • 13. Re: onSessionStart method runs on every request!??the
                                  sean69 Level 1

                                  That's interesting. Youre saying that an object stored in the application scope cannot be concurrently accessed by more than one user at a time even if no application scope variables [no scope lock] are being modified?

                                   

                                  if that is true, thats an important oversight on my part.... would you please  point me to some documentation on that?

                                   

                                  -thanks

                                  -sean

                                  • 14. Re: onSessionStart method runs on every request!??
                                    Dan Bracuk Level 5

                                    Having re-read the entire thing, I have these observations, questions and opinions.  No answers unfortunately, but maybe someone else will have an idea.

                                     

                                    Observation - worked in test, not on prod.

                                    Question - Did you test it with more than one user in test?

                                     

                                    Observation - You have a variable called session.startime that gets set to now() in onSessionStart.  You are also dumping the session scope in onSessionStart.

                                    Question - Are you seeing the value of that variable change on each page request?

                                     

                                    Observation - You have if/else logic in onRequestStart that includes the login page under certain circumstances.

                                    Opinion - Bad idea.  It will include the login page even after they successfully login.  At best, it will confuse people.

                                     

                                    Observation - You have at least one application variable that is an object containing various functions.

                                    Opinion - Good idea.  I misunderstood it the first time.

                                     

                                    Observation - You are dumping the session scope in onRequest.

                                    Question - Is the startime changing?

                                    • 15. Re: onSessionStart method runs on every request!??
                                      sean69 Level 1

                                      Hi Dan..... ok - it's back, will answer your questions first.

                                       

                                      Observation - worked in test, not on prod.

                                      Question - Did you test it with more than one user in test?

                                      I have tested it in 4 different browsers, 2 virtual machines + 1 vnc session*

                                      I get a new session every request in production but not in dvelopment.

                                       

                                      Observation - You have a variable called session.startime that gets set to now() in onSessionStart.  You are also dumping the session scope in onSessionStart.

                                      Question - Are you seeing the value of that variable change on each page request?

                                      Yes, the session starttime changes and I get a new session ID, every request.*

                                       

                                      Observation - You have if/else logic in onRequestStart that includes the login page under certain circumstances.

                                      Opinion - Bad idea.  It will include the login page even after they successfully login.  At best, it will confuse people.

                                       

                                      I'm not sure that's right if the session.authenticated ~is not~ session.sessionid then run the template if the user authenticates via the auth component then I set the session.authenticated to equal the session.sessionid

                                       

                                       

                                       

                                      "<cfif session.authenticated is not session.sessionid >"

                                       

                                      And technically that is an error, that should be a cflocation not an include.

                                       

                                      Observation - You have at least one application variable that is an object containing various functions.

                                      Opinion - Good idea.  I misunderstood it the first time.

                                       

                                      no worries.

                                       

                                       

                                      Observation - You are dumping the session scope in onRequest.

                                      Question - Is the startime changing?

                                       

                                      didn't we just go over this haha.. yes

                                       

                                       

                                       

                                       

                                      now on to the "*"

                                      firefox and opera work perfectly, they get one session and stick with it, IE and safari do not, they get a new session on every request.

                                      I have manually checed IE's cookies, they do not change - I can't find safari's

                                       

                                      now for more fun: I've stripped it down to nothing.

                                       

                                       

                                       

                                      <cfcomponent output="yes" >
                                          <cfscript>
                                              this.name = "233ad3";
                                              this.applicationTimeout = createTimeSpan(0,2,0,0);
                                              this.clientmanagement= "yes";
                                              this.loginstorage = "session" ;
                                              this.sessionmanagement = "yes";
                                              this.sessiontimeout = createTimeSpan(0,0,20,0);
                                              this.setClientCookies = "yes";
                                              this.setDomainCookies = "yes";
                                              this.scriptProtect = "all"; 
                                             
                                          </cfscript>
                                          <cffunction name="onSessionStart" output="yes" access="public" >
                                                  <cfset session.start = #now()# />
                                                  <cfdump var="#session#" />
                                          </cffunction>
                                      </cfcomponent>

                                       

                                      OK it just got funner-er Safari started working, all on it's own all I added was chenged output=true to output=yes. IE is still getting a nes session every request - and interestingly enough a new one on every change from compatibility to IE8 mode [or whatever]  [ ARRRGGH!! ]

                                       

                                      I'm storing cfclient data in a database on the server - I can see on every refresh that a new sessionid entry shows up in the database.

                                       

                                      I have a week to figure this out, now I'm getting worried.

                                       

                                      -sean

                                      • 16. Re: onSessionStart method runs on every request!??the
                                        BKBK Adobe Community Professional & MVP
                                        That's interesting. Youre saying that an object stored in the application scope cannot be concurrently accessed by more than one user at a time even if no application scope variables [no scope lock] are being modified?


                                        Yes. 

                                        • 17. Re: onSessionStart method runs on every request!??the
                                          sean69 Level 1

                                          hmmm...  I think it is cookies.

                                           

                                          logins work when I go to https://www.domain.com but not https://domain.com

                                           

                                          odd.

                                           

                                          irritating.

                                           

                                          and explains why it always works on the local server.

                                           

                                          looked into the non concurrency on the application scope objects, but could find no documentation that indicates this, BKBK, can you point me to some docs or a test case?

                                           

                                          -thanks

                                          -sean

                                          • 18. Re: onSessionStart method runs on every request!??the
                                            BKBK Adobe Community Professional & MVP
                                            logins work when I go to https://www.domain.com but not https://domain.com

                                            In Application.cfc or in the cfapplication tag in Application.cfm, ensure that


                                            setClientCookies = "yes"

                                            setDomainCookies = "yes"

                                             

                                            non concurrency on the application scope objects

                                             

                                            This is because Coldfusion is thread-safe. Search along the lines Coldfusion, thread-safety, cflock, race conditions.

                                            Good luck.