Variables in CFML; Session and Client Scopes

Like the Server and Application scopes the Session and Client scopes are both persistant and can exist across multiple requests. However each of these scopes is linked to a specific client allowing you to store information specific to each user of your application. Like the Application scope these scopes are only enabled by those requests using the <CFAPPLICATION> tag.

The Session and Client scopes can be considered children of the Application scope. Each named application has its own, private Session and Client scopes. This means that user can have Client or Session data in multiple applications on the same server at the same time with no conflicts or concurrency issues.

Both of these scopes require ColdFusion to uniquely identify end users in order to properly link them to their information. ColdFusion does this, by default, using the combination two generated values CFTOKEN and CFID. By default these values are sent to the client as cookies and will persist indefinitely. The values can also be appended to the URL of each ColdFusion request in those cases where cookies aren't desirable.

There are several important points to understand about CFTOKEN/CFID:

  • Since the CFTOKEN/CFID are the only information needed to link a user with their data placing the values on the URL is potentially dangerous as it could lead to session sharing. In other words multiple people could be linked, at the same time, to the same session. The most common cause of this is sharing URLs or bookmarking. You may want to read the Macromedia Support Center TechNote "Security Best Practice: URL Session Variables and HTTP_REFERER".
  • By default the <CFLOCATION> tag will automatically append the CFTOKEN/CFID to the URL specified. Unless this is desired behavior use the ADDTOKEN="No" attribute to prevent this.
  • The CFTOKEN/CFID is a sever-level assignment. That same set of values is shared by all applications on the server, although each application has distinct, private Session and Client scopes.
  • If you wish you may prevent ColdFusion from setting the CFTOKEN/CFID cookies using the SETCLIENTCOOKIES attribute of the <CFAPPLICATION> tag. You can then, if you choose, manually set the CFTOKEN/CFID cookies as non-persistent session cookies. We detail a technique for doing this in our article "Make Session Variables Truly Session Variables".
  • CFTOKEN/CFID are, by default, unique only for a specific server and may (although this is very rare) repeat on the same server (usually due to a server rebuild or restart). In CF 4.5 and later you may also opt to use globally unique identifiers. In CFMX this option is available in the CFAdministrator and in CF 4.5 and 5.0 it is a system registry change. Instructions for making the change are contained in the Macromedia Support Center TechNote "How to guarantee unique CFToken values".

The Session and Client scopes can be enabled or disabled using the SESSIONMANAGEMENT and CLIENTMANAGEMENT attributes of the <CFAPPLICATION> tag. As there is some overhead involved with using them it's recommended that they only be enabled if you are planning to use them.

With CFMX another option (available in the CFAdministrator) for uniquely linking the end user with the server-side Session (but NOT Client) scopes is to use the J2EE Session Management. This will create JSESSIONID variable at the start of each new session. This identifier can not persist like the CFTOKEN/CFID identifiers but does allow your CFMX application to seamlessly share session data with JSP pages or Java Servlets running on the same server.

Another potential benefit of using J2EE session management is that J2EE sessions can be replicated automatically across mutliple servers in a cluster. This eliminates lost sessions due to sever outages and routine maintenance. Sean Corfield, Macromedia's Director of Architecture in IT has a complete discussion on this topic available in his BLOG.

Session Scope

The Session scope is used to maintain data for currently active users. Like the Server and Application scopes the session scope is maintained in RAM and has the same limitations. Data stored in the Session scope can not exist across servers in a cluster and will not persist through a server/service restart.

The Session scope, like the Application scope, will time out after a set period of inactivity. Default and maximum timeout values may be set in the ColdFusion administrator. The default timeout for Sessions is 20 minutes. The timeout may also be set programmatically (but never higher than the maximum) using the <CFAPPLICATION> tag and the SESSIONTIMEOUT attribute. This attribute accepts the ColdFusion CreateTimeSpan() function.

Unlike some other application server solutions ColdFusion does not allow you to perform any actions upon the session timeout. In other words the session timeout does not throw a trappable event. You can mimic this by manually controlling the session timeout or by keeping (and manually managing) session-type information within the application scope or a database. Although these interim solutions are workable it is hoped that future versions of ColdFusion will allow for true end-of-session management.

There are several predefined variables contained in the session scope. These variables will exist in the default configuration:

  • Session.CFID: The CFID value.
  • Session.CFToken: The CFToken value.
  • Session.URLToken: This variable contains the CFID and CFTOKEN formatted for passage on the URL.

These variables will exist if J2EE session management is enabled:

  • Session.SessionID: The J2EE session ID.
  • Session.URLToken: This variable contains the CFID and CFTOKEN and the JSESSIONID formatted for passage on the URL.

Because the Session scope is maintained in RAM it may hold complex data types (structures, queries, etc). In ColdFusion MX you can also place instances of a CFC into the Session scope (a very powerful option). The Session scope is accessible as a structure in ColdFusion 4.5 and above.

Recommendations

Because the Session scope is persistent but not permanent (data won't survive a server reboot) it's recommended that it only be used to cache information and maintain application state. Information that must be collected from a database (especially if the queries involved are slow) or must be calculated are prime candidates for caching. You fetch or calculate the information only once and then store it for access in the session scope.

There are many scenarios where storing application state in the session scope can enhance the functionality and usability of an application. Storing user input during a multi-step process or user selections for later use (a shopping cart for example) are common examples of this.

Client Scope

The Client scope is designed to store more permanent information than the Session scope. It is not stored in RAM but rather uses one of several developer specified data storage interfaces. Although the possible storage mechanisms are all available manually the Client scope nicely abstracts them and provides some system generated values. A default storage mechanism can be defined using the ColdFusion Administrator and developer's may also define them at run time using the CLIENTSTORAGE attribute of the <CFAPPLICATION> tag. The available storage options are:

  • Registry: The Windows (or, on Unix, a simulated Windows) Registry. This option is not available in CFMX for Unix but is for earlier versions. Although this is the default storage mechanism (being available on all installations) we recommend that one of the other options be used. The registry is fundamental to the performance and stability of Windows systems and using it as a data storage area is potentially problematic.
  • Cookies: Client information will be stored in cookies. Although the most scalable solution (since no server-side resources are consumed) and usable across a cluster of servers cookies present two major problems. One, that the amount of information storable in a cookie is severely limited compared to other solutions and, two, that cookies are under client-side control and may be disabled.
  • Database: The value used in the CLIENTSTORAGE attribute is the name of a valid client storage datasource. The datasource must be created using the ColdFusion Administrator before it can be used for Client storage. Using a database for client information storage can be the best option. Unlike cookies the database is controlled server-side and doesn't have specific space limitations and unlike the registry there are no fundamental system performance or stability issues. Also any database accessible by ColdFusion can be used and the information is available across a cluster of ColdFusion servers.

The limitations and benefits of the Client scope depend greatly on the storage mechanism used however regardless of the mechanism only simple variables (no complex types) can be stored in the Client scope. You may choose to serialize complex values to a string using CFWDDX in order to store them in the Client scope.

The Client scope provides several predefined, read-only variables for your use:

  • Client.CFID: The CFID value.
  • Client.CFToken: The CFTOKEN value.
  • Client.HitCount: The total number of page requests made by the client.
  • Client.LastVisit: The date and time of the client's last visit to the application.
  • Client.TimeCreated: The date and time that the client first visited the application.
  • Client.URLToken: This variable contains the CFID and CFTOKEN formatted for passage on the URL.

The ColdFusion function GetClientVariablesList() can be used to return a list of all developer-defined variable names in the Client scope. The predefined variables described above will not be returned. The Client scope is accessible as a structure in CFMX and above.

Recommendations

It was already noted but it's worth repeating that the Registry is simply not a good place to store your Client information. In our opinion a Database is the best possible solution although this does require access to the ColdFusion Administrator (or a web host willing to configure a datasource for you). Cookies are a good option if the application doesn't require the client information to function (for example if the client information will only be used for system metrics or tracking) or if the application users can be forced to use cookies.

Whatever the storage mechanism the Client scope is a great abstraction for commonly used data. Although you could set the same information manually in a database or in cookies using the Client scope can be clearer and require much less coding and initial design.

322 Current Sessions; Time: 22:07:17 05-01-2009; Tick: 516