Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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?
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
If the if/else logic runs at onRequestStart, at what point does your authentication function have a chance to run?
Copy link to clipboard
Copied
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>
Copy link to clipboard
Copied
<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.
Copy link to clipboard
Copied
hmmm... no they are not. the fnctn & auth are objects defined in the application scope.
Copy link to clipboard
Copied
And BKBK was correct when he told you why that's a bad idea.
Copy link to clipboard
Copied
Your if/else logic in onRequestStart runs before any of that code.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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!
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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?
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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