1

I am building a website where I have followed MVC to manage my code without using any frameworks. I have put all of my queries inside cfcs and am initializing them inside my Application.cfm, storing them in application variables like below:

<cfset aplication.customerProfileObject=   
                createObject("component","cfc.customerprofile").init()>

To perform any query operations, I have made a function and then call it anywhere like this:

<cfset selectedCustomerOb =   
      application.customerProfileObject.getContactCustomerProfileDetail(session.userid)>

I don't know what is causing the issue, but sometimes a user accesses another user's data. How is that possible? Is it assessing another user's session data or have I initialized the cfc wrong?

Application settings are below:

<cfapplication name="MyDataSourceName" 
           sessionmanagement="Yes"
           setclientcookies="yes"
           setdomaincookies="yes"
           loginstorage="session"
           sessiontimeout="#CreateTimeSpan(0, 2,0,0)#">

CustomerProfile.cfc

<cfcomponent>
    <cffunction name="init">
        <cfreturn this> 
    </cffunction>

    <cffunction name="getContactCustomerProfileDetail" returntype="query"         
            description="Returns customer contact details by contactid" 
            access="public">
        <cfargument name="ccId" type="numeric" required="yes"> 

        <cfquery name="getContactCustomerProfileDetail" 
                  datasource="#Application.ds#" 
                  dbtype="ODBC" 
                  username="#Application.UserName#" 
                  password="#Application.Password#">
            <!-------My query here--->
        </cfquery> 

        <cfreturn getContactCustomerProfileDetail>

    </cffunction>

</cfcomponent>  
Leigh
  • 28,765
  • 10
  • 55
  • 103
user1728565
  • 117
  • 1
  • 8
  • 2
    What if `session.userid` is blank? Would your CFC return the first (or maybe all) `customerprofile` record(s)? – beercodebeer Dec 13 '13 at 21:01
  • 1
    Do you have the code for Skyhook `getContactCustomerProfileDetail()` – James A Mohler Dec 13 '13 at 21:02
  • 4
    Sounds like something's not appropriately scoped in the CFC. – ale Dec 13 '13 at 23:05
  • Please post the code for customerprofile.cfc – Russ Dec 14 '13 at 06:49
  • If session.userid is blank system will logged out. – user1728565 Dec 14 '13 at 17:17
  • customer profile component code is here- – user1728565 Dec 14 '13 at 17:19
  • Are you using UUID for CFToken in the CF Administrator? – BKK Dec 15 '13 at 07:11
  • No.I am using jsessionid. – user1728565 Dec 15 '13 at 11:49
  • @user1728565 - When storing cfc's in a shared scope like application, properly localizing **all** function local variables is a must. Otherwise you run into weird threading problems like this, as Adam mentioned. You need to go back over your cfc and make sure **all** function local variables are `var/local` scoped - including query names. (Also, nothing to with your question but I believe dbtype="ODBC" is deprecated). – Leigh Dec 15 '13 at 19:20
  • (Edit) *RE: storing them in application variables like below* As an aside, are you are checking to see if `application.customerProfileObject` was already initialized first? If not then you are re-instantiating the component each time the Application.cfm is processed, which defeats the purpose of using an application variable. – Leigh Dec 15 '13 at 19:40

2 Answers2

4

As Adam says you need to do this:-

<cffunction name="getContactCustomerProfileDetail" returntype="query"         
        description="Returns customer contact details by contactid" 
        access="public">
    <cfargument name="ccId" type="numeric" required="yes">

    <cfset var getContactCustomerProfileDetail = false>

    <cfquery name="getContactCustomerProfileDetail" 
              datasource="#Application.ds#" 
              dbtype="ODBC" 
              username="#Application.UserName#" 
              password="#Application.Password#">
        <!-------My query here--->
    </cfquery> 

    <cfreturn getContactCustomerProfileDetail>

</cffunction>

The reason you are getting the problem is because your CFC instance is in a shared scope (application) and you have not var'd the query variable. This means that it is getting set into the variables scope of the CFC instance. Which means that multiple threads can overwrite this value. By just varring the variable as I have shown you make the variable local to the function and so each call to that function creates a localised and thus thread-safe variable.

Basically you should var all local variables in functions as a matter of habit. This code would never pass code review anywhere I have worked.

baynezy
  • 6,493
  • 10
  • 48
  • 73
3

You're not actually including the relevant bit of the code to answer this... which would be the code within getCustomerProfileDetail().

However I would assume you don't have all your variables VARed in it, which means they go in the CFC's variables scope, which is shared with every user in the application.

But, as I say, you're not giving us the correct info to really answer this accurately. I suggest updating your question to include the relevant code.

Adam Cameron
  • 29,677
  • 4
  • 37
  • 78