SessionTimeout not overrriding CF Administrator - coldfusion

I've got a website with a simple login. After 20 minutes, if the user has been inactive, his session expires, and if he tries to save his work (usually a book review that takes longer than 20 minutes to complete), he's logged out and loses everything.
The code is six years old and I was never able to solve this problem. I was using application.cfm at the time, and have now replaced it with application.cfc:
<cfcomponent>
<!--- Set up the application. --->
<cfset THIS.Name = "SCR" />
<cfset THIS.ApplicationTimeout = CreateTimeSpan( 0, 12, 0, 0 ) />
<cfset THIS.SessionManagement = true />
<cfset THIS.SessionTimeout = CreateTimeSpan( 0, 3, 0, 0 ) />
<cfset THIS.SetClientCookies = false />
<cffunction name="onRequestStart">
<cfargument name="requesturi" required="true"/>
</cffunction>
My login code sets the user's info like this:
<cfif getLoginUser.recordcount eq 1>
<cfset session.user_id=getLoginUser.user_id>
<cfif getLoginUser.user_level_id eq 1>
<cfset session.user_type=1>
<cfelseif getLoginUser.user_level_id eq 2>
<cfset session.user_type=2>
<cfelseif getLoginUser.user_level_id eq 3>
<cfset session.user_type=3>
</cfif>
<cfset session.user_name='#name#'>
<cfif not isdefined('session.redirect_url')>
<cflocation url="my_account.cfm">
<cfelse>
<cflocation url="#session.redirect_url#">
</cfif>
</cfif>
A look at the output of cfApplicationSettings confirms these settings, but the 20 minute timeout continues without fail. I am on shared hosting with no access to the CF Administrator, but it's my understanding that these settings should override that. The only time I seem able to override is if I make the sessiontimeout LESS than 20 minutes...it's happy to expire the session in a minute if I tell it to.
I'm a bit out of the loop on anything since about ColdFusion 5. (I believe the host is running 9 now.), so if there's something totally inept in my cfc I wouldn't be at all surprised.
Thanks.

Per the ColdFusion documentation: " you cannot set a time-out value [in Application.cfc or Application.cfm] that is greater than the maximum session time-out value set on the Administrator Memory Variables page."
Since you are on shared hosting, if your host won't increase the timeout (and they probably won't), you're going to have to rethink your application flow.
One possible workaround is to use periodic AJAX requests to keep the session alive. Tie the requests to a JavaScript timer based on keypress activity.

Related

trying to check for a session if itexist and has value

i am writing a code to check for session and session value and if they do not exists or exists but have empty value or 0, i want them redirected
here is my start
<cfset lstofSessionsToCheck = 'EmplyID,Username'>
<cfset st = {}>
<cfloop collection="#session#" item="i">
<cfset SetVariable("st.session.#i#",duplicate(session[i]))>
</cfloop>
<cfparam name="redirection" default="false">
<cfif session.Username eq ''>
<cfset redirection = true>
<cfelseif session.EmplyID eq ''>
<cfset redirection = true>
</cfif>
it is missing some checks here
check if session is defined before it checks its value
if its defined, its value should not be empty or 0 or -1
please guide,m i am almost near its end but stuck at that
session is a special scope in ColdFusion and either always or never exists. It depends on the state of the sessionManagement attribute in your Application.cfc (or Application.cfm/<cfapplication>). In case sessionManagement is false, accessing session will immediately throw an exception. I assume you are not seeing this error, so session management is enabled in your environment. That leaves you with checking if the session fields are initialized. Your new best friend is called structKeyExists().
<!--- username needs to exist and must not be empty --->
<cfset hasUsername = (
structKeyExists(session, "Username") and
(len(session.Username) gt 0)
)>
<!--- ID needs to exist, must be a number and > 0 --->
<cfset hasID = (
structKeyExists(session, "EmplyID") and
isNumeric(session.EmplyID) and
(session.EmplyID gt 0)
)>
<!--- if either username or ID is not properly set, do a redirect --->
<cfif (not hasUsername) or (not hasID)>
<cfset redirection = true>
</cfif>
You can simplify the last line to a single expression:
<cfset redirection = ((not hasUsername) or (not hasID))>
As for your usage of setVariable(): You should generally avoid this function (along with evaluate()) as they can be easily exploited and pose a security risk.
Rewrite:
<cfset st = {}>
<cfloop collection="#session#" item="i">
<cfset SetVariable("st.session.#i#",duplicate(session[i]))>
</cfloop>
to
<cfset st = {}>
<cfset st.session = {}>
<cfloop collection="#session#" item="i">
<cfset st.session[i] = duplicate(session[i])>
</cfloop>
(And by the way, i is actually a key here, not a numeric index. Only use i with a for loop.)
I'm not sure the best way to do this is by looping through the entire thing every time you check. Unless those values are coming from a database or something after authentication?
Typically, if you want to restrict access to a page, you would check the session scope using structKeyExists(), for just a couple specific things.
The code would look something like this:
<!---This code sees if the user is logged in at all. If they are missing important information, I clear the session scope and redirect them to the login page. --->
<cfif !structKeyExists(SESSION, 'Username')>
<cfset structClear(SESSION)>
<cflocation url="YourPageHere" addtoken="maybe">
</cfif>
<!---This code checks for a specific permission to be defined. If not, it stops or redirects the user.--->
<cfif structKeyExists(SESSION, 'CanEditUsers') AND SESSION.CanEditUsers eq 1>
<!---your code here--->
<cfelse>
<cflocation url="YourPageHere" addtoken="maybe">
</cfif>
This is only a rough example - but hopefully puts you on the right path. Let me know if anything is unclear or needs to be edited to better fit your situation.

Invalid Component Definition

I'm having an issue in the logs I cannot replicate on the browser. I'm getting hundreds of these per day
invalid component definition, can't find component [cfc.udf]
The cfc are stored in a cfc folder one level above the app. This is so that many apps can use the same cfc.
Folder structure:
---- cfc
--------- udf.cfc
---- myApp
--------- application.cfc
In the application.cfc, I'm using application-specific mappings because this is set on a lot of different load-balanced-servers in production as well as a QA environment and local testing environment and keeping them all synced would be difficult.
At onRequestStart, I have a function that restarts the application every 5 minutes. It was supplied by a consultant. I suspect that this is the culprit because the logs show these errors coming in at exactly 5 minute intervals
<cfcomponent>
<cfset This.name = "myApp">
<cfset This.Sessionmanagement=true>
<cfset This.Sessiontimeout="#createtimespan(0,0,30,0)#">
<cfset this.mappings['/cfc'] = ExpandPath('../cfc')>
<cffunction name="onApplicationStart">
<cfset Application.udf = createObject("component", "cfc.udf").init()>
</cffunction>
<cffunction name="onRequestStart">
<cfset appRefreshMinutes = 5>
<cfif Not IsDefined("Application.refreshTime")>
<cfset currentMinute = Minute(Now())>
<cfset Application.refreshTime = DateAdd("n", -(currentMinute MOD appRefreshMinutes)+appRefreshMinutes, Now())>
<cfset Application.refreshTime = DateAdd("s", -(Second(Application.refreshTime)), Application.refreshTime)>
</cfif>
<cfif Now() GTE Application.refreshTime Or IsDefined("URL.reload")>
<cflock name="ApplicationInit" type="exclusive" timeout="5" throwontimeout="false">
<cfif Now() GTE Application.refreshTime Or IsDefined("URL.reload")>
<cfset OnApplicationStart()>
<cfset Application.refreshTime = DateAdd("n", appRefreshMinutes, Application.refreshTime)>
</cfif>
</cflock>
</cfif>
</cffunction>
</cfcomponent>
Promoted from the comments
Have you tried using a mapping name other than /cfc? Like:
<cfset this.mappings['/somethingelse'] = ExpandPath('../cfc')>
so that you can then call it like:
<cfset Application.udf = createObject("component", "somethingelse.udf").init()>
Maybe it just looks odd to me or maybe that is causing your issue (cfc being a reserved word or somehow getting special treatment in this case).

ColdFusion 10 Error occurring only in IE9

My customer is encountering the error The 2 parameter of the Left function, which is now -1, must be a positive integer after migrating from ColdFusion 8 to ColdFusion 10. The page performs as expected in Firefox 31 and Chrome 36 on Windows 7. However, this error occurs in IE9 but not IE7. Are there different security settings in IE9 that prohibit the processing of the code?
The snippet of code in question is:
<!--- Populate the UserInfo struct --->
<cfloop INDEX="item" LIST="#COOKIE.MYELVIS_USERINFO#" DELIMITERS="&">
<cfset delim = #FindOneOf("=",item)#>
<cfif (len(item)-delim)>
<cfset UserInfo[UCase(left(item,delim-1))] = right(item,len(item)-delim)>
<cfelse>
<cfset UserInfo[UCase(left(item,delim-1))] = "">
</cfif>
</cfloop>
I'm torn to say it's a code error when it works in other browsers, just not IE9. Any thoughts? Thank you.
Perhaps have him clear cookies, he might have a holdover from cf 8 and perhaps the two versions encode differently. It looks like, if this is possible, one of the values doesn't contain a =.
Upon reviewing your code, I think this is what you need.
<cfloop INDEX="item" LIST="#COOKIE.MYELVIS_USERINFO#" DELIMITERS="&">
<cfset delim = #FindOneOf("=",item)#>
<cfif (delim) and (len(item)-delim)>
<cfset UserInfo[UCase(left(item,delim-1))] = right(item,len(item)-delim)>
<cfelse>
<cfset UserInfo[UCase(item)] = "">
</cfif>
</cfloop>

Setting up Session variable in Application.cfc

Hi I'm very new with ColdFusion 10 especially with Application.cfc. It is very confusing.
I created Application.cfc and inside this cfc I created the following:
My questions are:
1. Why do I get session error? (see my codes below)
2. What should I put in sessionEnd function?
<!--- Application.cfc --->
<CFCOMPONENT displayname="Application" output="true">
<cfset THIS.Name = "MyTestApp" />
<cfset THIS.ApplicationTimeout = CreateTimeSpan(0,0,60,0) />
<cfset THIS.SessionManagement = true />
<cfset THIS.SessionTimeout = CreateTimeSpan( 0, 0, 30, 0 ) />
<cfset THIS.SetClientCookies = false />
<cfset THIS.SetClientCookies = false />
<cffunction name="OnApplicationStart" access="public"
returntype="boolean" output="false">
<cfset application.Main_DSN = "MyTestDB">
</cffunction>
<cffunction name="onApplicationEnd" output="false">
<cfargument name="applicationScope" required="true">
</cffunction>
<cffunction name="OnSessionStart" access="public" returntype="void" output="false"
hint="Fires when user session initializes">
<cfset session.loggedin = "NO">
<cfset session.username = "">
<cfset session.userrights = "">
<cfset session.usergroup = "">
</cffunction>
<!--- After user login, I have checklogin.cfm --->
<cfif mylogin NEQ true><!--- Login failed, go redirect to login page --->
<cflocation url="login.cfm">
<cfelse>
<cfset session.loggedin = "YES"><!--- ??? error: see below --->
<cfset session.username = "#Trim(Form.username)#">
<cfset session.userrights = "#Trim(Form.userrights )#">
<cfset session.usergroup = "#Trim(Form.usergroup)#">
</cfif>
<cffunction name="onSessionEnd">
<!--- Not sure what can I put in here????? --->
</cffunction>
Your login code is outside any of the event handlers in your Application.cfc file, so that code will run first... before any of the event handlers!
The execution sequence of code in Application.cfc is:
code outside of any event handler (irrespective of where it is in the file)
onApplicationStart()
onSessionStart()
onRequestStart()
etc
So you cannot have code referencing the session scope (or application scope for that matter) outside the other event handlers. You can only start using session variables once onSessionStart() has fired. Not before.
What is the error message that you are getting?
You can really put anything in the session end. Anything that you would need to run to clean up after a session.
Maybe you want to update a log or send an email, clear a cookie, or redirect to a certain page.
EDIT:
Is everything else in the Application.cfc working for you? It seems like the onSessionStart event is not firing.
EDIT 2:*
Sorry for doing this via an answer but I need more rep to leave comments.
The session should start as soon as you connect to the application, you do not need to wait to be "logged in" as in verify credentials.
If the session variables do not exist then the event is not firing for some reason. Make sure you have the file name correctly and it is in the root folder of the application.
EDIT 3:
Your login code is not in the onSessionStart function, not in any function. Unless I misunderstood your comment and you were saying that code section is in the "checklogin.cfm" file and not in the Application.cfc file.
EDIT 4:
I need to jump on a client call but I can help some more after. We might need to take a look at part of the checklogin.cfm file.
EDIT 5:
Any luck?
EDIT 6:
Sorry for the delay, volume is ramping up this afternoon.
At this point I think I would either need to see the code that is doing the validation checking or ask if you are sure the validation is working correctly.
I assume you are connecting to a database, if you take the query you are using to verify the login credentials and run it in SQL server or whatnot inserting the values you would type into the form, do you get any results?
EDIT 7:
Figure it out, OP?

Can CFThread, when wrapping over cfhttp, solves my Timeout error issue?

My application pulls lots of data from different applications according to the selected scopes. For e.g. Org level and SubOrg level scopes, this can cause to bring server down and everyday causes server crashing and timeouts.
So I wanted to know whether wrapping cfthread around my cfhttp will solve my timeout problem?
<cfinclude template="fundedScopes.cfm">
<!--- Call the funded scopes --->
<cfset dynVarName = "funded" & bizforShort>
<cfif structKeyExists(variables,dynVarName)>
<cfset howManyCustomScopes = listLen(structkeylist(variables[dynVarName],"|" ),"|" )>
<cfmodule template="#Request.Library.CustomTags.VirtualPath#Scheduler_LogDetail.cfm"
Step="Funded Level Cache" Detail="Custom Scopes to be cached: #howManyCustomScopes#"
LogData=""></cfmodule>
<cfloop collection="#variables[dynVarName]#" item="t">
<cfset tempurl = variables[dynVarName][t]["url"]>
<cfset tempurl = tempurl & "&retainCache=1">
<cfoutput>
<cfhttp url="#tempurl#" method="GET" resolveurl="false" timeout="3000">
#tempurl#<br>
<cfset scopesCachedCounter = scopesCachedCounter + 1>
<cfmodule template="#Request.Library.CustomTags.VirtualPath#Scheduler_LogDetail.cfm" Step="Funded Scopes Cache" Detail="#scopesCachedCounter#.- #t#" LogData="#tempurl#"></cfmodule>
</cfoutput>
</cfloop>
</cfif>