Setting ColdFusion Cookies With CFCookie vs. Cookie Scope

Posted May 3, 2010 at 8:15 AM by Ben Nadel

Tags: ColdFusion

Yesterday, as I was working on my Scotch On The Rocks (SOTR) ColdFusion Framework presentation, I discovered a huge error in my understanding of the way in which cookies can be set in ColdFusion. For years, I thought the difference between the CFCookie tag and the Cookie scope was that only the CFCookie tag caused the given cookie to be sent to the client where as the cookie scope was just a regular struct. Meaning, you could use the cookie scope to store arbitrary values; but, if you wanted to send cookies to the client, you needed to do so with the CFCookie tag.

I don't know when or how I formulated this belief but, as I found out yesterday, it happens to be completely wrong. As it turns out, both the CFCookie tag and the Cookie scope send cookies to the client. The only real difference between them is that CFCookie gives you more control over how the cookies are sent to the client. When you use the Cookie scope directly to set a cookie, it creates a session cookie (which expires when the browser is closed) for the current domain. CFCookie, on the other hand, gives you the ability to control all aspects of the cookie including its domain, pathing, and secure page usage.

To demonstrate this, I set up this snippet of code:

  • <!--- Set a cookie with CFCookie. --->
  • <cfcookie
  • name="setWithCFCookie"
  • value="true"
  • expires="never"
  • />
  •  
  • <!--- Set a cookie directly with COOKIE scope. --->
  • <cfset cookie.setWithCookie = true />

As you can see, I am setting cookies using both the CFCookie tag as well as the raw Cookie scope. When we run this code, we see the following page response activity in Firebug:

 
 
 
 
 
 
Setting ColdFusion Cookies With The CFCookie Tag vs. The Cookie Scope. 
 
 
 

As you can see, both approaches sent cookie headers to the client; the only difference was that the cookie set via the Cookie scope has no expiration date (session cookie).

In order to do this, the Cookie scope has to be special; it doesn't constantly re-send all the available cookies - it only sends the cookies that were created in the current request. As such, I figure that the cookie scope must have some sort of implicit setter methods that "listen" for property updates. And, when they detect that the cookie scope has been programmatically mutated, it knows to add additional Headers to the response. Out of curiosity, I dump'ed out the underlying Java class and got this:

coldfusion.runtime.CookieScope

Clearly, the cookie scope is not a standard ColdFusion struct (coldfusion.runtime.Struct). This must be how it knows to set additional response headers as the name-value cookie pairs are set. Luckily, as my pervious view on cookies was "stricter" than necessary, it never caused unexpected behaviors. But, now that I know that I don't need to use the CFCookie tag all the time, direct use of the cookie scope will be a very nice and easy way to create session cookies.



Reader Comments

May 3, 2010 at 8:27 AM // reply »
2 Comments

Hi Ben

Thank you for this post. I currently work for a company that uses ColdFusion to build web apps. I'm not sure, if my colleagues know about this. Now I have a link to point them to. Thx again.

Chat with you later!

Pat


May 3, 2010 at 8:31 AM // reply »
11,246 Comments

@Patrick,

I've been using ColdFusion for years; it's a little embarrassing that I didn't know about such a fundamental behavior of the language. I figured if I didn't understand it then there might be others who didn't get it either.


May 3, 2010 at 9:00 AM // reply »
6 Comments

didn't know that either, thanks for the post!


May 3, 2010 at 9:02 AM // reply »
11,246 Comments

@Chris,

Cool - glad I could help. I've been misinformed on this for so long, I can't even remember how I formed my previous understanding. I could swear I was taught this way.


May 3, 2010 at 9:04 AM // reply »
2 Comments

You don't have to be embarrassed. Nobody knows everything :-)

I've checked Abode Livedocs, because I wondered what Adobe has to say. The behavior is documented, but I haven't noticed it until your post.

So... thanks again :-)

Pat


May 3, 2010 at 9:09 AM // reply »
11,246 Comments

@Patrick,

I appreciate the kind words.


May 3, 2010 at 10:10 AM // reply »
29 Comments

Very interesting piece of knowledge to store away for the future....


May 3, 2010 at 10:58 AM // reply »
30 Comments

Ben, I just made this "discovery" myself about two weeks ago. Like you I thought the only way to send set-cookie headers was using cfcookie, but I was obviously wrong. I wonder if this behavior changed at some point?

Anyway, one other thing I will add to this is that using StructDelete() on the cookie scope will also send set-cookie headers. For example, StructDelete(cookie,"setWithCookie") will send the following headers:

Set-Cookie SETWITHCOOKIE=;expires=Sun, 03-May-2009 14:55:02 GMT;path=/

Notice ColdFusion clears the value and sets the expiration date to a date in the past.


May 3, 2010 at 9:47 PM // reply »
1 Comments

Great. I was wrong too, though that's the same meaning :D

Thank Ben, it's absolutely small discovery but big meaning to us :D


May 4, 2010 at 5:56 PM // reply »
11,246 Comments

@Nathan,

Oh nice! I didn't even think to test the structDelete() usage on cookie. I guess that makes sense though (from a consistency standpoint). I really feel like this must have changed at some point; or, I was simply taught incorrectly at some point.

@Quang,

Excellent - glad to help clarify.


Apr 10, 2011 at 6:58 PM // reply »
50 Comments

Any one know how to set a cookie for multiple domain extentchins - domainone.com , domainone.ca, domainone.in


May 15, 2011 at 9:05 PM // reply »
12 Comments

@Ben,

Thanks for posting this. I used to get a lil confused between these two approaches and at some point pushed it to the side thinking that it's just 2 ways of accomplishing the same thing.

Evidently not! It's good to know the subtle but important distinction. Thanks again!

-roger


May 16, 2011 at 8:48 PM // reply »
11,246 Comments

@James,

I don't believe that that is possible; I'm pretty sure that would be considered a security concern. But, beyond the COOKIE scope, my understanding is not so thorough.

@Roger,

No problem at all. When in doubt, I just tend to use CFCookie to set values. The only time I use the Cookie scope to set a value is when I am CFParam'ing it; and, that is only when I don't need it to last that long. Since they are session cookies (no expiration date - what happens when you set the cookie value directly in the scope), they only last for the duration of the browser.


Oct 13, 2011 at 9:39 AM // reply »
1 Comments

I believe to set the cookie for multiple domains you use multiple <cfcookie>'s changing the domain for each one in your list.


Apr 17, 2012 at 8:48 AM // reply »
2 Comments

Hey Ben, I just wanted to say thanks for the info, I just started working with cookies in a CF site and this helps.

One question though, is it possible to update the cookie's value (noob question I know :P) But basically when a user comes to my site, a cookie called "Cookie_UID" is created and given a value of 0 (just a generic UserID). Then once a specific user logs in, I want to update that "Cookie_UID" to be the user's actual UserID. I can post my code here if you'd like, but I didn't want to fill up too much space :)

Thanks again for the info!

~Sean



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 25, 2013 at 10:08 AM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
@Ben, my question is that i want the current node with its tag and its parent node. i just want only that data. So, give me the solution for that. and remember solution is working on " xpath 1.0 ... read »
May 25, 2013 at 10:01 AM
Using "//" And ".//" Expressions In XPath XML Search Directives In ColdFusion
hey ben, i want get my current node tag and also want the root node tag withing. So, how can i fix it.. ! ... read »
May 24, 2013 at 5:39 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Adam Oops! My mistake! I hadn't gotten that far in my testing - I'm still baby stepping my way through the process. ... read »
May 24, 2013 at 5:13 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
Hi Jason, Thanks for checking up on that, but I still stand firm on my position. :) There are actually two listLast()'s in use, and you're right that the one using a space as a delimiter is fine. ... read »
May 24, 2013 at 4:45 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Ben I have been lurking your site for quite some time, and haven't stepped up to comment until today. Thanks for all the great info - keep it up! @Adam I believe you are mistaken... as the commen ... read »
May 24, 2013 at 11:21 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@WebManWalking, Ha ha, let's us never speak of justifying "##" notation again :P ... read »
May 24, 2013 at 11:18 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, Ah, so it was indeed how I vaguely remembered it to be: A direct assignment value = users.id[ i ] causes value to retain the sticky datatype of the query column. Although unnecessary in ... read »
May 24, 2013 at 9:11 AM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Brandon, Hi, No, I haven't been able to do that. I have just kept it as it is. ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools