A year or so ago I posted an entry explaining why, as a rule, managing session state on the server (as ColdFusion does) was not ideal in Flex applications. I still stand by that assertion. But, many have pointed out that it is sometimes necessary to access ColdFusion session data from within Flex applications. Indeed, I was asked about this several times in the past week alone. And so, time to update the topic.
ColdFusion stores session variables on the server. In order to know which subset of session data belongs to a specific client, ColdFusion creates an identifier that is sent to the client (usually as cookies, but it could also be a URL parameter). The identifier must be sent back to ColdFusion on each and every subsequent request so that ColdFusion may make the correct server-side session data available. Without the identifier, ColdFusion will assume that there is no active session, and will the create a new session and attempt to send a new identifier to the client.
Flex applications run within the Flash Player, not within ColdFusion. As such, Flex applications have no direct access to ColdFusion session data. But, if you were to create a Flex application with a ColdFusion back-end, that Flex application could indeed gain access to ColdFusion session data as needed. Here’s how it works.
The preferred way for Flex to connect to ColdFusion is via Flash Remoting – using AMF to connect to a ColdFusion Component. AMF actually communicates back to ColdFusion via HTTP and the web browser. As such, if ColdFusion’s session identifier exists in the browser, it will be sent back with Flash Remoting requests. Similarly, if the browser receives identifier cookies along with AMF results, those cookies will be saved. In other words, when you use to connect to a ColdFusion Component, ColdFusion is fully aware of session state management, and the CFC being invoked automatically has access to the correct session data.
But, how can Flex get to that data? The answer is it can’t, but you can create a CFC that exposes session variables.
Caution: Before you go further I will point out the obvious. If you create a public facing CFC that exposes methods that allow session data to be directly manipulated, well, you’ve now allowed public access to session data. Of course, callers will only have access to their own session data, but still, proceed with caution, and make sure you fully understand what you are doing.
Ok, here is the session.cfc file:






























As you can see, the code is pretty simple. SESSION is actually a ColdFusion structure, and so direct session access is possible using CFML structure functions. The “list” method returns an array of session variables (their names). The “get” method gets the contents of a specific session variable. And the “set” method sets a session variable, creating or updating as needed (this example only creates simple variables). The final method, named “keepAlive” does nothing, and it can be called as needed to keep the session alive (ensuring that it does not time out).
To help test the app (and to populate it with data) you can use a simple test page like this:











Variable:

Value:




How to use session.cfc from within Flex? Here is a simple example application:












The application features two panels. The first displays a list of ColdFusion session variables (by calling the session.list() method), allowing them to be selected to display their contents (by calling the session.get() method). The second contains a form that can be used to create new session variables (by calling the session.list() method). To ensure that the ColdFusion session does not time out, a Flash timer is defined, and it pings the keepAlive() method (once a minute in this example).
Now, I would still caution you by saying that, as a rule, if data needs to persist it should persist on the client, within the Flex application. But, when you do need access to ColdFusion session data, this technique will do the trick.
Updated 11/16/2007 to add timer and keepAlive logic.

42 thoughts

  1. Ben, great example, thank you – I actually expected this to be alot harder that it was. Just a quick question – what is it that "links" the flex app to the created session. I nearly expected to see a "urltoken" being passed when I first started reading the post. Is the relationship to the session CFC maintained by the connection opened in the Flex app, or is it done via the browser?
    Also, there are different ways to manage sessions in CF (cookies, database, J2EE, etc), will this method work with them all?
    Cheers,
    Davo

  2. David, it works just like regular sessions work. As the request is routed via HTTP and the browser, the same CFID/CFTOKEN cookies are set and passed back and forth. If cookies are not used then it’ll be trickier, as you’d need to pass the identifier manually.
    — Ben

  3. Thanks for the update. However, you still don’t address the issue of keeping the session from timing out, do you have any insight to this matter?
    To clarify, the flex app running in the flash player does not refresh the browser, and so after about 20 minutes the session times out and is rendered useless. If it is not possible to increase the timeout value for sessions passed 20 minutes due to limitations imposed by the server administrators, you are %@&#.
    Is there a way to use remoting to refresh the session and/or keep it alive? Or are we stuck with a sessionless solution?

  4. Clint,
    Sure, all you need to do is ping a CF page or CFC method on the server ever n minutes. For example, add a CFC method called keepAlive() which does nothing, and use an ActionScript timer to invoke it every few minutes. Problem solved.
    — Ben

  5. Clint,
    I just updated the example to include the keepAlive logic I was referring to. The example now pings the server once a minute, just to keep the session alive.
    — Ben

  6. Ben, you say if data needs to persist it should persist on the client (the flex application). How can this be secure? If I store the fact that a client is authenticated, or that their user_id is N, whats to stop them from modifying that data as its passed back to the server? Say when the getAccountDetails(user_id) method is called or whatever.
    Instead we’ve been doing getAccountDetails(), (without passing in a user_id parameter) and then internally the getAccountDetails method always looks to Session.user_id.

  7. Ryan,
    I agree, there is persistent data and then there is persistent data. While the authenticated user id should definitely be tracked in the client, it must be validated on the server (although users can always change session identifiers, user tampering is a reality either way, and it must be dealt with). But, other data, like contents of a shopping cart, definitely belong on the client. I guess we need them both.
    — Ben

  8. Ben / Ryan,
    Your replies bring up great points – so if I may ask a follow up question (that may be slightly OT) – how secure is the persistent data stored in the Flash Player. So, if user_id is passed from your CFC to Flex, is it possible for the user to then manipulate the user_id to do some snooping in your system? I was always under the impression that the flash player was secure from such manipulation.
    Thanks,
    David

  9. I’ll let Ben comment on the security of the flash player itself – but its fairly easy to run the AMF/HTTP data through a proxy where I could manipulate the data as it passes through. There are also FireFox extensions that will record the AMF/HTTP data, allow you to change it, and then play it back – thus bypassing the flash player all together.

  10. David, regardless of the client used, as a rule, anything on the client can be changed, and whatever is sent over the wire can be intercepted. Which is why server side validation is never optional.
    — Ben

  11. Fantastic, thanks.
    But one problem: when I use HttpService, such as when I call HttpService.send(http://…), also the server need an user identification. Than how we can send the session value the same time?

  12. There are some situations the flashplayer won’t send along the cookies at all.. I forgot if it was IE on windows or Firefox on windows though..

  13. Ben, I read your previous article several times before setting up my integrated flex / cf site with common authentication and data model (in CFC’s). This one validates the reasons and approach I ended up going with.
    Hope this isn’t too off topic…I’m using a combination of PureMVC in Flex and Coldbox on the CF side. Because the coldboxproxy exposes the Coldbox handlers and Coldbox provides session access plugins (along with a lot more) creating mixed XHTML/Flash apps with shared data and communication has been pretty easy. The Coldspring integration, interceptors, logging, caching and debugging features of Coldbox are also great and using the coldboxproxy they are easily applied to the AMF requests coming from Flex. Setting up a generic coldboxproxy Business Delegate in PureMVC with specific handlers called from Proxies was easy (one I got my head around all the OO / design patterns stuff). Hope some of this is useful to others, I’m still figuring a lot of it out.
    Thanks to Luis (Coldbox) & Cliff (PureMVC), their frameworks rock and they are both very supportive and responsive to feedback and questions. Thanks again to you Ben, I got started with CF 2 and your books really helped along the way.
    Chris

  14. Hi Ben,
    In your session.cfc, is it best practice to use cflock when using the set and get methods?
    Thanks in advance!
    Andrew

  15. Andrew, I am not sure I’d call it a ‘best practice’, misused it could be far from the best anything. But, if you are concerned about race conditions, then yes, use a session lock.
    — Ben

  16. ok, anything on the client is accessible/changeable. I use MVC for my flex application. Model of the MVC stores all my data in the form of value objects. these data are exposed through the controls and databinding. I make service calls to php services to save data in the database. what is the security issue involved with this type of architecture?

  17. I try to run the example:
    the CF testpage works fine, but the Flex App returns the following error:
    Unable to invoke CFC – Variable SESSION is undefined.

  18. Quick question on this topic of sessions, flex and coldfusion:
    1. When the user logs in and is verified I store a hashed (cftoken + username) on the client side.
    2. I also update that into the my webuser table of the database.
    3. Then everytime the user sends a request through flex I have a cfc w/ stored procedure that checks against the hashed(cftoken + username) and cftoken in the database.
    4. OnSession end it clears it from the database table.
    * I always check user permissions server-side against the database
    Wouldn’t this for the most part keep everything as secure as a standard coldfusion web app?
    If this is basic I apologize… just started using Flex

  19. Alex, that probably means the session identifier is not being passed. You need to verify that.
    Steve, yes, that will indeed keep things as secure. But the main reason to keep client state information on the client is less about security and more about performance, manageability, and the fact that that is where it belongs. The reason that we store client session state information on the server in web apps is not because that is where it belongs, it’s because of a fundamental limitation of the wen in that it is stateless. Flex apps do not have this limitation. So it is less about doing things the way we do in web apps, and more about not having to resort to doing so. Of course, some things do belong on the server, like login timeouts. But other things belong on the client.
    — Ben

  20. Ben,
    Can you tell me what you means with "…that probably means the session identifier is not being passed. You need to verify that…", please?

  21. Ben,
    I have a slightly different twist on this SESSION issue. I am doing a client app that calls for give-and-take between the server and several different types of clients — IM, SMS, Email. I have them all working just fine if I initiate the session from the client side. I can send in an IM to the server (or an email or sms) and it keeps track of the session just fine.
    But there will be times when I need the SERVER to initiate the session, and I still want the client to use that session. For instance, I’m going to send an appointment reminder from the server to the client. The client may want to respond with "Cancel", but if I don’t have a live session, I don’t know what appointment they’re talking about, so now I have to ask them to pick an appointment.
    From the client side, they’re saying "Hey, stupid, you sent me the reminder! You should know!"
    How do I force the client to accept the session that the server initializes? I have not figured out the key to this … yet…
    RLS

  22. Randy, take Flex out of the equation for a second …
    If you pick a CFID and CFTOKEN, or start a session that generates these, you can use <cfcookie> to set this on the client, and then the client will send those back. You have now set the session you want them to use.
    So, if you send them an email message, for example, have the linked page generate the session, or you can even (and I am not sure I like this, but it demonstrates the point) you can even pass CFID and CFTOKEN in the URL in the message you send.
    — Ben

  23. Ben,
    Thank you for your reply. I must admit that I interjected a non-Flex question into this Flex-related thread. Flex was never part of my problem, so I apologize for that confusion and for busting into a thread like that.
    I had not been using a linked URL inside of the Email. I could for the email messages and the IM’s, I suppose, but if they send an SMS, not all people have a data plan so I cannot be sure they’ll be able to link up.
    If the server initiates the thread, and all the client does is REPLY, whether by SMS, Email, or IM, they will initiate a new session because there is no link, no visibility to the server session by the client, and no way for me at the server’s initial thrust to write to the clients device. If I cannot get the client to run a URL — and part of the appeal of our system is that they don’t have to — then I cannot write a cookie.
    I am not sure there is a solution here, for creating any other way for the client to access the session identification that the server initiated, other than searching a short-list table for that clients identification (SMS number, IM buddy name, email address) and establishing the variables of their current session with what’s required in the response, thereby matching the new client session with the original values found in the server’s session.
    Does that make sense? Or is there some trick or function that I’m missing here that would make my job not only a lot easier but also a "safer"? The problem lies when there are more than 1 outstanding request to be handled for that client. Then I need to come back first and ask them which request they are responding to, an extra step that could be avoided if I could force them to use my server-originated session.
    RLS

  24. Yep, wrong thread, but …
    Actually, sessions should work regardless. If you create a SESSION variable in a request that came in via SMS or IM, then the session ID should be tied to the identifier used on that gateway. Of course, you’d not be able to initiate the session that way, but if there was some identifier in the request that you coudl use then onSessionStart you could populate it as needed.
    — Ben

  25. Hi Ben,
    Was going through the long time thread on Session Management through flex. Have found that this is the best info available on net on this concept.Kudos to you for keeping it going for these many years.
    I have a Reporting application of Flex+J2EE.I need to store a connection object in session.If it is not stored in session on first go, then I need to open a new one everytime.How can I store this in Flex?
    Sorry for the long mail.
    Manesh.

  26. I know this is probably a really simple question, but using the above example, how can I grab a specific session variable from within Flex.
    For example, I’m trying to get the session variable "SESSION.auth.name" and bind it to a label in Flex.
    So far I just haven’t been able to figure out what seems would be really easy (and likely is) to do.
    Thanks!

  27. Ok, Ben, help me out! I know that you mentioned above that the message ‘variable SESSION in undefined’ means that the session variables aren’t being sent to/from Flex/CFC.
    WHAT DOES THAT MEAN? AND HOW CAN I GET THEM TO ‘SEND’. I’ve been on this problem for days now and it’s getting frustrating!
    I’m running Flex Builder 3, with 3.2 SDK, and CF8. My CFCs are all remote and all CFCs that do not reference SESSION.xxx or APPLICATION.xxx work perfect.
    As sample CF code that throws an error is the following:
    <cfif IsDefined(SESSION.CLIENT.boolClientLoggedIn)>
    <cfif SESSION.CLIENT.boolClientLoggedIn eq "true">
    <cfthrow message="Attempting to call fncClientWebSignup when client is logged in.">
    </cfif>
    </cfif>
    my RemoteObject Call is:
    <mx:RemoteObject id="cfc_Client" destination="ColdFusion" source="_Controller.cfc_Client" showBusyCursor="true">
    <mx:method name="fncClientWebSignup" result="handleWebSignupResult(event)" fault="faultHandler(event)"/>
    </mx:RemoteObject>
    Preemptively, THANK YOU!!!

  28. There are no session variables in flex… You need to look at using singletons to track this information within flex; at least that’s what I ended up doing.

  29. Ok, that’s a start.
    Can you give me a bit more detail/resources/code snippets as to how you used singletons? (Excuse a n00b 🙂 )

  30. Good day all,
    A related question to this perhaps the best thread on the web on session variables in Coldfusion and Flex; My understanding is whether you access a CFC from Flex (more accurately a flash movie built in Flex) via an HTTP request, a web service, or Flash remoting, the communication goes through the browser and so reaches the server as an HTTP request. In other words, the ColdFusion server does not really care if the CFC was called from a CFM page or from a Flash movie via some kind of RPC. Correct?
    If the ColdFusion server does not care whether the call to the CFC comes from a CFM page or a Flash movie, then it is fair to assume that calls coming from a Flash movie will be assigned a unique CFID and CFTOKEN, which really are how the server keeps track of which client is associated with which session scope. Correct?
    If a browser-request to a CFC is assigned a unique CFID and CFTOKEN regardless of whether the browser is playing a Flash movie or is showing a CFM page, then it is fair to assume that the ColdFusion server can maintain server-side variables associated with the requesting browser in session scope, client scope, and pretty much any other scope that is based on individual CFID and CFTOKEN pairs. Correct?
    If all of the above is correct (i.e. if my understanding of the mechanics of ColdFusion server is correct), then the following example is correct:
    Step 1. Browser makes a request to a ColdFusion server for a Flash movie that shows a login form.
    Step 2. CF Server initiates a session and onSessionStart() is called. Server sends movie to client’s browser. onSessionStart() sets a SESSION scope variable SESSION.boolUserLoggedIn = false.
    Step 3. Client fills the form in the Flash movie and hits the login button. The login button calls a CFC function on the CF Server that validates the client’s credentials.
    Step 4. CF server receives a Flash remoting request from the client to invoke the function ValidateClient() defined inside User.cfc.
    Step 5. ValidateClient() runs. If the credentials are valid, the session variable boolUserLoggedIn is set to true. The server returns a boolean true to the client indicating that the login was successful.
    Step 6. Client receives the boolean return value of the function ValidateClient(). If the value is true, the user is logged in and the user homepage is displayed inside the Flash movie.
    Step 7. User wants to delete his/her account, so they click on a Delete Account button in their Flash movie which now shows their homepage since they are logged in. The Delete Account button invokes function DeleteAccount() in the same User.cfc file.
    Step 8. CF server receives the Flash remoting RPC to DeleteAccount() in the User.CFC file. User.CFC is invoked.
    Step 9. The first line of DeleteAccount() checks whether the user is logged in or not, in other words, the first line of DeleteAccount() checks the session variabl SESSION.boolUserLoggedIn. Since the CF server is maintaining these session variables server-side and these variables are identified by a CFID and CFTOKEN pair that the browser passes everytime it makes a request to the CF server, the DeleteAccount() method has access to the client’s SESSION scope server-side. The method sees that the client is logged in and so proceeds to delete his/her account.
    The above is essentially what I am doing, yet when DeleteAccount() is called in Step 9, a fault is raised saying that SESSION is undefined.
    Why? Where in my assumptions have I gone wrong?
    Thanks all.

  31. Hi Ben,
    I stumbled across this post looking for information regarding the use of Session/Application variables with LiveCycle Data Services and ColdFusion Assembler/DAO cfc’s. I tried the method here with no succes… it seems that a new session is created with each DataService instance in Flex calling a destination through LiveCycle DS.
    So… can you tell me… am I swimming up stream here? I’d really like to be able to set a session variable to represent my datasource destination so that I can have multiple database versions all using the same set of CFC files, but after a few days of hacking at this, I just can’t make it work.
    Help 🙁

  32. The CF test page doesn’t work properly. I know it’s my mistake.
    Could you figure out what it is?
    It shows the error message as below:
    Could not find the ColdFusion component or interface session.
    Ensure that the name is correct and that the component or interface exists.
    The error occurred in C:ColdFusion9wwwrootemicrofinancetest.cfm: line 10
    8 : method="set"
    9 : name="#Trim(FORM.varName)#"
    10 : value="#Trim(FORM.varValue)#">
    11 : </cfif>
    12 :
    It appears when I click "Save SESSION variable" button. .
    Look forward to your reply.
    Thanks in advance.

  33. Is there any way to *share* sessions between two Flex programs?
    Let’s say I use one Flex program to create a session, then from within that Flex program I call another Flex program and pass it the first program’s session ID via the calling URL.
    I then want the second program to use that Session ID to read the session variables that were set in the session of the first Flex program.
    Is that at all possible?

  34. I’m sorry to keep bothering you, but I’m having trouble with the same thing that Alex posted about, way back in April of ’08…
    I keep getting "Variable SESSION is undefined" errors.
    You say that this is caused by the session identifier not being passed — ok fine.
    HOW do I pass this identifier? To where do I pass it? How do I even access the identifier? I thought all that took place in the background — your code here makes no reference to any session identifier at all, so I’m completely confused…
    Thanks,
    L.

  35. I’m confused… I create session variables in one Flex program, then call a second Flex program from within that first program. Shouldn’t the two programs share the same session? Shouldn’t I be able to access the session variables in the second Flex program? Whenever I try to access the session variables in the second Flex program, they’re all blank. I have no idea what I’m doing wrong…

Leave a Reply