View Single Post
Old 04-08-2010, 03:51 AM   PM User | #7
Gjslick
Regular Coder

 
Join Date: Feb 2009
Location: NJ, USA
Posts: 476
Thanks: 2
Thanked 70 Times in 69 Posts
Gjslick will become famous soon enough
Hey code L, no problem. Try this out as your Application.cfm file:
Code:
<cfapplication 
    name="MyApplication" 
    applicationTimeout="#createTimeSpan( 2, 0, 0, 0 )#"
    sessionManagement="true"
    sessionTimeout="#createTimeSpan( 0, 0, 20, 0 )#" 
    setClientCookies="true">
    

<!--- Set session loggedIn key --->
<cfif NOT structKeyExists( session, "loggedIn" )>
    <cflock scope="session" type="exclusive" timeout="10">
        <cfif NOT structKeyExists( session, "loggedIn" )>    <!--- Test again inside lock --->
            <cfset session.loggedIn = false>
        </cfif>
    </cflock>
</cfif>


<!--- If the user is not logged in, and they are not on the login or login processing page, 
            then redirect them back to login.cfm --->
<cfset targetPage = cgi.SCRIPT_NAME>
<cflock scope="session" type="readonly" timeout="10">
    <cfset loggedIn = session.loggedIn>
</cflock>
<cfif NOT loggedIn AND targetPage neq "/login.cfm" AND targetPage neq "/login_process.cfm">
    <cflocation url="/login.cfm">
</cfif>
The complex looking locking code that sets the session.loggedIn variable is only needed for the rare chance that two threads will be updating the key at the same time for the same user (i.e. the user opened two browser windows, your site is in frames, etc), but better safe than sorry. Can't remember if CFMX suffers from the possibility of memory corruption when multiple threads are accessing shared memory at the same time, or if they had fixed that issue by then. I'm pretty sure versions up to CF5 did have the possibility of that problem tho.

That outer <cfif> around the exclusive lock is for performance reasons, as there is a little overhead involved in creating a lock, but the lock is only needed on the user's first request for a page to your site. After that, session.loggedIn will have been created, and there is no reason to create an extra lock each time a page is requested from then on. The readonly lock is still needed though.

Speaking of which, the other pages should change slightly too to incorporate shared memory locks as well. I think I just wanted to make the code be simple originally, but they should have had them all along

login_process.cfm:
Code:
<cfif form.username eq 'test' AND form.password eq 'test'>
    <cflock scope="session" type="exclusive" timeout="10">
        <cfset session.loggedIn = true>
    </cflock>
    <cflocation url="memberWelcome.cfm">
<cfelse>
    <cflocation url="login.cfm?invalidLogin=true">
</cfif>
logout.cfm:
Code:
<cflock scope="session" type="exclusive" timeout="10">
    <cfset session.loggedIn = false>
</cflock>


<cflocation url="login.cfm">
Let me know how that goes.

-Greg
Gjslick is offline   Reply With Quote