Setting Cookies In CFScript Using Structs In ColdFusion 10
The other day, I was looking at some code in a part of InVision App that I don't usually work on when I saw something in ColdFusion that I had never seen before. Devin Schulz, one of our excellent front-end engineers, was using a struct to set a Cookie value in CFScript. It looks like this feature was added in ColdFusion 10, so I'm clearly a few years behind the curve here. In order to drill this concept into my head, I wanted to put together a quick little demo.
You've always been able to set a cookie value in CFScript. But, early on, you could only set the cookie value using a simple string. This approach ends up creating a "session cookie" that expires when the user closes the browser. To cope with this limitation, many people ended up creating something like a setCookie() helper method that was defined using ColdFusion tags in order to expose the full CFCookie functionality.
In ColdFusion 11, we finally got full tag support in CFScript. Which means that, in ColdFusion 11 or later, we can use CFCookie natively in CFScript using the method-like syntax, CFCookie().
But, in ColdFusion 10, unbeknownst to me, the CFCookie functionality gap could be bridged using a Struct. With this approach, the struct contains the configuration for the cookie value. This includes keys like "value", "expires", and "httpOnly." Now, the documentation on this states that this approach also supports "name" and "preserveCase"; however, these two properties do not appear to actually do anything (at least not that I could see). I thought maybe "name" and "preserveCase" would came into play when trying to structAppend() a value to the cookie scope; but, this doesn't appear to be a supported feature of the scope.
Anyway, to see this in action, I'm going to set a cookie using three different approaches: using a simple string (ColdFusion 9), using a struct (ColdFusion 10), and using the CFScript tag access (ColdFusion 11):
<cfscript>
// When setting the cookie as a simple value, you end up creating a "session cookie"
// for the current domain that will expire when the user closes their browser.
// --
// NOTE: I'm using bracket-notation when setting the property in order to maintain
// key-casing on the cookie name since I don't have "preserveCaseForStructKey" turned
// on in this application.
cookie[ "asString" ] = "Woot woot!";
// As of ColdFusion 10, you can set the cookie value as a struct that contains the
// details of the cookie configuration.
// --
// NOTE: I'm using bracket-notation when setting the property in order to maintain
// key-casing on the cookie name since I don't have "preserveCaseForStructKey" turned
// on in this application.
cookie[ "asStruct" ] = {
value: "Woot woot!",
expires: dateConvert( "local2utc", dateAdd( "n", 30, now() ) ),
domain: "testing.bennadel.com",
httpOnly: true
};
// CAUTION: The documenation says you can use the "name" and "preserveCase"
// properties in this above approach; however, neither seem to do anything. Also,
// you cannot use this approach to structAppend() the value to the cookie scope.
// ------------------------------------------------------------------------------- //
// ------------------------------------------------------------------------------- //
// If you are running on ColdFusion 11 or later, you can access all ColdFusion
// tags from within CFScript by using the tag's name. This includes the CFCookie tag.
// --
// NOTE: Notice that, when using the tag accessor, we have to use "preserveCase" in
// order to maintain the key-casing on the cookie name.
cfcookie(
name = "asCFCookie",
value = "Woot woot!",
expires = 1,
domain = "testing.bennadel.com",
httpOnly = true,
preserveCase = true
);
</cfscript>
As you can see, the struct allows us to provide the same keys that you would ordinarily supply to the CFCookie tag. And when we run the above code and look at the network activity, we get the following:
As you can see, it works like a charm! This is super helpful - I wish I had known about this years ago. But, better late than never, I suppose, especially since I am still running ColdFusion 10 in several production applications. Much thanks to Devin for showing me the light!
Want to use code from this post? Check out the license.
Reader Comments
Ben, is it possible to just update one attribute like:
cookie[ "asStruct" ] = {httpOnly: true};