Alan asks an interesting question about sessions:
Raymond, here's a follow up to the application.cfc deal. If I have an extranet site and I want external users' sessions to time out, but I don't want internal users to time out, can I put a call to reset a session in the onSessionEnd() event for my internal users that will re-establish their session?
So to be clear, you can call onSessionEnd() (and onApplicationEnd()) all you want, but it won't be a "real" end of session type action. As far as I know, there is no way to say, this user's session will expire in N minutes, and this user's session will expire in M minutes. I think you could address this with some custom coding.
First off - I assume when the user logs on, you have some kind of marker for internal versus external users. Next - I'd add a marker that represents their last hit. So in onRequestStart you could do:
<cfset session.lastHit = now()>
Now you know the last time the user hit the site. So to handle extranet users and their smaller time frame, you would check the dateDiff from their last hit to now. If it is greater than the smaller time frame, you can log them out.
How do you log them out? That depends on your application. If you are using session.loggedin to mark a user as being authenticated, simply remove that variable. In theory, that should cover it. If your onSessionEnd does other stuff, like maybe log a file, you may want to abstract that to another method. Let's call it sessionCleanUp. Then both onSessionEnd, and your onRequestStart can call the same method when they need to.
I really feel like I'm not being clear here - but do folks get my drift? Have people had to deal with something like this before?
Archived Comments
Ray,
You were definiatly on the right track. We have a website that is external, however we have internal people hitting it through an internal ip address. The way I determine who is who, is by the CGI.REMOTE_ADDR. If I see that it starts with the internal ip (ie. 10.0) then I know they are internal. With that bit of information I can then use a simple if statement to execute code. So if I have a statement that logs a person out after a certain amount of time, I can choose not to run if for the internal people:
<cfset variables.isinternal = false>
<cfif ListFirst(cgi.REMOTE_ADDR, '.') EQ 10>
<cfset variables.variables.isinternal = true>
</cfif>
<cfif DateDiff(n, seesion.lastvisit, now()) GTE 15 AND NOT variables.variables.isinternal>
<cfset session.token = "">
</cfif>
We have a custom made javascript that will keep someone logged in. You set it to a timeout just before your session timeout and if the browser stays open on a single page for longer than the alloted time it issues a refresh. The only problem is on pages that you post to, but I never have the user on a page that is posted to. I either use gets or if I need a post, I post to an action page and redirect to the next page.
I would be willing to share if you would like it. You could put it in where the code only runs if they are certain users im sure.
Ray and everybody - thanks a ton. I think we have what we need to solve our problem. Ray, you da man.
Just to be a security nag here, it's better if you don't rely on the remote IP as that's pretty easy to spoof. As Ray mentioned, a better way would be to have a flag in your db/ldap that marks a user as internal or external. It'll save you problems down the road should you start mixing in things like VPN/webVPN access, etc.
we are not on CF7 yet...approach on CF < 7...two cfapplication tags, err names rather? In my experience, the remote IP would be the proxy server if the user is accessing via extranet and not spoofable, but this may depend on your extra/intranet setup. some psuedo code
If remoteip == proxy server
appname = extranet
sessiontimeout = 20
else
appname = intranet
sessiontimeout = 60
end if
cfapplication name="#appname#" sessiontimeout="#sessiontimeout#"
would this not work? how to do this on CF7 eh?