Sunday, November 8, 2015

CfWheels and Controller Init Caching Gotcha

I recently discovered an issue where logic inside of a controllers init gets cached when your environment is set to production. By default, when in the production environment the cfwheels setting of cacheControllerInitialization defaults to true.
At the time I had logic in the init method that checks if the user agent is CFSCHEDULER and the remote address is localhost/127.0.0.1. I used this logic to authenticate scheduled tasks that run on a secure section of the site.
I found this when sporadically the authentication would pass even though the logic returned false and I noticed the init method was _never_ being called, which led me to find that caching setting.
The fix was to extract the logic out into another method and add that to the list of filters.


/************** Before **************/
<cffunction name="init">
    <cfif CGI.remote_addr EQ "127.0.0.1" AND CGI.HTTP_USER_AGENT EQ "CFSCHEDULE">
        <!--- let the CF ScheduledTask pass through --->
        <!--- add custom logic to impersonate authenticated user --->
    <cfelse>
        <cfset filters(through="getCurrentUser,isAuthenticated,isAdmin", type="before")>
    </cfif>
</cffunction>

/************** After  **************/
<cffunction name="init">
    <cfset filters(through="isScheduledTask,getCurrentUser,isAuthenticated,isAdmin", 
        type="before")>
</cffunction>

<cffunction name="isScheduledTask">
    <cfif CGI.remote_addr EQ "127.0.0.1" AND CGI.HTTP_USER_AGENT EQ "CFSCHEDULE">
        <!--- let the CF ScheduledTask pass through --->
        <!--- add custom logic to impersonate authenticated user --->
    </cfif>
</cffunction>

1 comment: