11 Replies Latest reply on Nov 23, 2008 4:57 AM by BKBK

    OnRequest with CFC

    Qais Level 1
      I know that OnRequestStart and OnRequest run at the top of each request, but is there a way to consider a call (invoke) for a CFC as a request ? What I need is to use either OnRequestStart or OnRequest with any invoke for a CFC to do some logic check before it excute the function in the CFC. I may have 2 or 3 invokes in the same page. one more thing just in my case, all the CFCs I have are initialized on Application scope.

      Any suggestions ?
        • 1. Re: OnRequest with CFC
          Level 7
          > I know that OnRequestStart and OnRequest run at the top of each request, but is
          > there a way to consider a call (invoke) for a CFC as a request ?

          If one calls a CFC method as a web service, it is a fully-fledged request
          in itself. I wouldn not recommend this approach though, because there'd be
          quite a performance hit.

          I think you should ask yourself the question - or explain to us better -
          why it is you want/need to re-invokve the processing from onRequestStart()
          / onRequest() *again*, for CFC method calls within the same request. It
          sounds to me like the code in your onRequest methods aren't really specific
          to the request.

          Perhaps you should factor-out the required functionality from your
          onRequest method(s), and put it somewhere else, calling it both from the
          onRequest and other methods.

          You could look at ColdSpring for handling stuff like automatically calling
          [other functionality] whenever any old CFC method is called.

          --
          Adam
          • 2. Re: OnRequest with CFC
            Qais Level 1
            I need to use one of those methods as a security gateway, so in theory, this should run first (OnRequestStart or OnRequest ), if you pass the security requirments then continue the call/invoke, otherwise reject it before it reach CFC.
            • 3. Re: OnRequest with CFC
              Level 7
              > I need to use one of those methods as a security gateway, so in theory, this
              > should run first (OnRequestStart or OnRequest ), if you pass the security
              > requirments then continue the call/invoke, otherwise reject it before it reach
              > CFC.

              Right. So if this check is done in onRequestStart, why do you need to do
              it *again* for a CFC method call within the request?

              --
              Adam
              • 4. Re: OnRequest with CFC
                Qais Level 1
                Because I want to make that check for each CFC invoke, and in some cases I may have 2-3 invoke in the same page, OnRequestStart or OnRequest runs only once on at the top of page request, in my case I need to consider each call to a CFC as a request and will run OnRequestStart or OnRequest.

                maybe what I'm asking can be approach in another way but if I can run those methods for each CFC call that will be great in my case.
                • 5. Re: OnRequest with CFC
                  Level 7
                  > Because I want to make that check for each CFC invoke, and in some cases I may
                  > have 2-3 invoke in the same page, OnRequestStart or OnRequest runs only once on
                  > at the top of page request, in my case I need to consider each call to a CFC as
                  > a request and will run OnRequestStart or OnRequest.

                  Wanting to do it is one thing. I understand you want to. But *why* do you
                  think you need to?

                  At the beginning of the request you do some security checks. I presume if
                  the security checks "fail", then processing is halted.

                  So for requests have passed the security check, processing continues.

                  A CFC call is encountered.

                  You want to run the same security check again. But it's already been done.
                  What's the point of doing the check again? What're you checking that could
                  reasonably be expected to have changed in the few milliseconds we're
                  talking about? And surely a check being made on onRequestStart() is
                  intrinsically "good" for the whole request?


                  Note I'm saying there's no reason, what I *am* saying is you're not
                  explaining yourself. To answer the question, you need to explain why you
                  want to do this (beyond just "because" ;-)

                  So what's this check doing, and why is it you need to do it more than just
                  at the beginning of the request?

                  --
                  Adam
                  • 6. Re: OnRequest with CFC
                    Qais Level 1
                    ok Adam, to give you an example, let's say (for example) I have a CFC call on line 10 to get and display member info, and on line 20 I have another call to different CFC where you want to show some private info for that member and only admin level can see it. and let's assume I have 3 level of permissions (none, basic and advance), for the none level, both shouldn't run and should display something else, for basic they will see only the return for the first call, while advance can see the return of both CFCs, this is just an example and hope I'm explaining it well this time, now some people may say that I could approach this in another way, but I'm just trying to ask people here if one those 2 methods can be called upon each CFC invoke, and thanks for all the feedback.
                    • 7. Re: OnRequest with CFC
                      Level 7
                      Qais wrote:
                      > but I'm just trying to ask people here if one those 2 methods can be called upon each CFC invoke

                      Lets settle this one. *NO*

                      Directly invoking a local CFC within CFML is *NOT* a 'request' and does
                      not trigger in events inside the Application.cfc framework. The request
                      this is referring to is an HTTP request through a web server. So calling
                      local memory objects within the ColdFusion Application server is not
                      going to trigger anything.

                      If you want these events triggered when calling a CFC, then that CFC is
                      going to have to be accessed through a web server. CFC's do support
                      this so that they can be used as web services, but you will then
                      experience all the performance costs of working with your CFC's as web
                      services not local memory objects.

                      The two that come to the top of my mind is that web services would be
                      much slower and it is much more difficult to persist an objects internal
                      data from request to request.

                      • 8. Re: OnRequest with CFC
                        Level 7
                        Ian Skinner wrote:
                        > Qais wrote:
                        >> but I'm just trying to ask people here if one those 2 methods can be
                        >> called upon each CFC invoke
                        >
                        > Lets settle this one. *NO*
                        >

                        I'm going to amend this.

                        They could be called if you wish to do so directly. But they will never
                        be called on any 'request' event. But since an application.cfc is still
                        just a regular cfc, there is nothing, technically, preventing you from
                        instantiating it and calling any of its methods as you would any other cfc.

                        • 9. Re: OnRequest with CFC
                          Dan Bracuk Level 5
                          quote:

                          Originally posted by: Qais
                          ok Adam, to give you an example, let's say (for example) I have a CFC call on line 10 to get and display member info, and on line 20 I have another call to different CFC where you want to show some private info for that member and only admin level can see it. and let's assume I have 3 level of permissions (none, basic and advance), for the none level, both shouldn't run and should display something else, for basic they will see only the return for the first call, while advance can see the return of both CFCs, this is just an example and hope I'm explaining it well this time, now some people may say that I could approach this in another way, but I'm just trying to ask people here if one those 2 methods can be called upon each CFC invoke, and thanks for all the feedback.

                          For your specific example, I would use a session variable to identify the level of permission. Then I would use that variable to determine whether, or how to call the methods on lines 10 and 20.

                          I see no reason to put anything related to this in the onRequestStart method of your application.cfc.
                          • 10. Re: OnRequest with CFC
                            Level 7
                            OK, the requirement makes sense, but not the way you're trying to implement
                            it.

                            So the given *user* has some security checking that needs to be done.
                            That's a session-level thing, not a request-level thing to me.

                            I would create some sort of security context in onSESSIONstart(), and do
                            the initial user validation there, say:

                            // onSessionStart()
                            session.oSecurity = createObject("component", "UserSecurity").init()

                            Then in onRequest() I would check if that user has any sort of access to
                            the resource being requested.

                            // onRequest()
                            if (bPageIsASecureOne IMP session.oSecurity.isLoggedIn()){
                            // proceed
                            }else{
                            // go login first
                            }

                            The login bits identifies the user, and goes grabs their general access
                            levels.


                            And then, if within one of your templates you need to check for an auth
                            type, do this:

                            // show the Admin stuff
                            if (session.oSecurity.isAdmin()){
                            // show the thing that needs admin access
                            }else{
                            // don't
                            }

                            // show the advanced stuff
                            if (session.oSecurity.isAdvanced()){
                            // show the thing that needs admin access
                            }else{
                            // don't
                            }

                            // show the basic stuff
                            // no need for anything special here, possibly, because isLoggedIn()
                            implies adequate access?

                            The isAdmin() and isAdvanced() return a boolean based on whatever rules you
                            have to make the determination. If it's specific to the what's on the
                            template (someone might be admin of one page, but not on another), then
                            you'd need to pass something in identifying where the isAdmin() check is
                            being called from. This could be done in onRequest(), I suppose, with a:

                            session.oSecurity.setAdmin(resource=targetPage)

                            But I'd be cautious of this because I'm inclined to only do processing *if
                            I need it*, and not all URLs might have a isAdmin() consideration.


                            I imagine there are other approaches too, but I doubt any of them would
                            rely on recalling onRequestStart() / onRequest(), because that's not
                            logical.

                            --
                            Adam
                            • 11. OnRequest with CFC
                              BKBK Adobe Community Professional & MVP
                              Qais wrote:
                              ... What I need is to use either OnRequestStart or OnRequest with any invoke for a CFC to do some logic check before it excute the function in the CFC. I may have 2 or 3 invokes in the same page.... one more thing just in my case, all the CFCs I have are initialized on Application scope.

                              ...let's say (for example) I have a CFC call on line 10 to get and display member info, and on line 20 I have another call to different CFC where you want to show some private info for that member and only admin level can see it. and let's assume I have 3 level of permissions (none, basic and advance), for the none level, both shouldn't run and should display something else, for basic they will see only the return for the first call, while advance can see the return of both CFCs, this is just an example and hope I'm explaining it well this time, now some people may say that I could approach this in another way, but I'm just trying to ask people here if one those 2 methods can be called upon each CFC invoke...


                              I would put code in onRequestStart to determine whether the user's permission level is none, basic or advance. It might likely involve using <cfloginuser>, where the roles attribute can have the value none, basic or advance. I would store that permission information in session scope.

                              I would then create a CFM page to run the remaining logic. It would have the following logic:

                              <cfswitch expression="#session.permission#">
                              <cfcase value="none">
                              Display something else
                              </cfcase>
                              <cfcase value="basic">
                              create CFC_1 object, CFC_1_obj
                              call CFC_1_obj.displayMemberInfo();
                              </cfcase>
                              <cfcase value="advance">
                              create CFC_1 object, CFC_1_obj
                              call CFC_1_obj.displayMemberInfo();

                              create CFC_2 object, CFC_2_obj
                              call CFC_2_obj.showPrivateInfoForMember();
                              </cfcase>
                              </cfswitch>