maxwellg
14 hours ago
Cookies are filled with weird gotchas and uncomfortable behavior that works 99.95% of the time. My favorite cookie minefield is cookie shadowing - if you set cookies with the same name but different key properties (domain, path, etc.) you can get multiple near-identical cookies set at once - with no ability for the backend or JS to tell which is which.
Try going to https://example.com/somepath and entering the following into the browser console:
document.cookie = "foo=a";
document.cookie = "foo=b; domain=.example.com";
document.cookie = "foo=c; path=/somepath";
document.cookie
I get 'foo=c; foo=a; foo=b'
treflop
11 hours ago
At work, whoever designed our setup put the staging and dev environments on the same domain and the entire massive company has adopted this pattern.
What a colossal mistake.
NavinF
8 hours ago
Yep. Even within the prod environment it's ideal to have a separate domain (as defined by the Public Suffix List) for sketchy stuff like files uploaded by users. Eliminates a whole class of security issues and general fuckery
jamesfinlayson
8 hours ago
I had the option to re-use the prod domain for non-prod a few years ago (the company's other two projects use the prod domain for all non-prod environments).
I didn't really think about cookies back then but it just felt like a generally bad idea because disastrously messing up a URL in some config or related service would be much easier.
teaearlgraycold
8 hours ago
For the juniors reading this, here's what you do:
Buy a second domain, ideally using the same TLD as your production domain (some firewalls and filters will be prejudiced against specific TLDs). Mimic the subdomains exactly as they are in production for staging/dev.
anonfordays
5 hours ago
Just use subdomains such as *.dev.example.com, *.test.example.com, *.prod.example.com, etc., no?
mcfedr
5 hours ago
The reason not to do that is that dev.example.com can set cookies on example.com and other envs can see them.
jan_g
4 hours ago
We have *.example.dev, *.example.qa, *.example.com for development, staging/qa and production. Works well and we haven't had any issues with cookies.
thayne
4 hours ago
That only works if you (and any third party code that might run on such a domain) are completely consistent about always specifying the domain as one of your subdomains whenever you set a cookie.
And if your marketing/SEO/business people are ok with having something like "prod" as a subdomain for all your production web pages.
sensanaty
an hour ago
Usually it's mainsite.com for the marketing site, and then app.mainsite.com for actual production, or if you have multiple it'll have the product name, like coolproduct.mainsite.com
We then have app-stg and app-canary subdomains for our test envs which can only be accessed by us (enforced via zero trust). No reason for marketing or SEO teams to care in any case.
netdevphoenix
3 hours ago
When was the last time you saw a public website like that? prod.companyname.com websites are extremely rare especially outside tech.
graemep
an hour ago
The production site could be www. or something else that makes sense.
teaearlgraycold
5 hours ago
Ah yes if you use a CNAME that would work. You know better than me.
anal_reactor
10 hours ago
I'm sure this will be replicated in future projects because it's much easier to argue "we're already following this pattern so let's be consistent" than "this pattern is bad and let's not have two ruined projects"
spacebanana7
12 hours ago
I wonder if this explains a lot of the unusual behaviour that happens when you use multiple accounts on a website in the same browser.
sureIy
6 hours ago
Seems perfectly reasonable to me?
If you are on /somepath I'd expect to get C as is the most specific value out of all three. All the values are still returned, ordered, which to me is the best of both worlds (path-specific values + knowing the globals)
The only thing I don't like is the magic `document.cookie` setter, but alas that's nearly 30 years old.
draw_down
13 hours ago
Yeah, isn’t that how you represent a list of values? (Or maybe better to say a collection, not sure if ordering is preserved)
kevincox
13 hours ago
But if the attributes are exactly the same then the cookies replace each other. So this isn't a general mechanism for representing a list.
Not to mention that the way to delete a cookie is sending a replacement cookie that expires in the past. How are you supposed to delete the right cookie here?
maxwellg
11 hours ago
And the worst is that you need to exactly match the domain and path semantics in order to delete the cookie! Domain is easy enough because there are only two options - available to subdomain and not available to subdomain. But if you have a cookie with the `/path` set and you don't know what value was used, you literally cannot delete that cookie from JS or the backend. You need to either pop open devtools and look at the path or ask the end user to clear all cookies.
HappMacDonald
11 hours ago
Is there a way for JS to see the attributes for each value? Because presumably setting an expire time in the past and iterating over every used set of attributes would get the job done to delete the cookie. Iterating over all possible (plausible?) attributes may also work, but knowing the specific attributes set would narrow that list of erasing writes to issue.
kijin
7 hours ago
No, there isn't. All you get a list of values that are valid for the current page. Same on the server side.
If you're ever in a situation where you need to invalidate all possible instances of a cookie, it's easier to just use a different name.
teaearlgraycold
11 hours ago
Using the path field is a code smell
NBJack
11 hours ago
Can you elaborate? I'm having a tough time finding references to that. (Disclaimer: I'm not an avid JS developer)
kijin
7 hours ago
It means that you are setting cookies on whatever page you're on, without considering whether the cookie will be consistently accessible on other pages.
For example, you set the currency to EUR in /product/123, but when you navigate to /cart and refresh, it's back to USD. You change it again to EUR, only to realize in /cart/checkout that the USD pricing is actually better. So you try to set it back to USD, but now the cookie at /cart conflicts with the one at /cart/checkout because each page has its own cookie.
oneeyedpigeon
an hour ago
If you want cookies to be global, set them to / or leave out the path. If you want more fine-grained cookies, use a specific path. What's the problem? Currency is—in your example—clearly a site-wide setting. I think sites should make more of their hierarchical structure, not less.
foldr
2 hours ago
Isn't that just the feature working as intended? Of course it is possible to introduce a bug by setting or not setting a cookie somewhere where it should/shouldn't be set.
I've never found a use for path-based cookies personally, but I'm not sure this is a particularly compelling example.
teaearlgraycold
11 hours ago
For modern applications you’ll have better ways to maintain state. As shown they cause trouble in practice. Cookies should be used sparingly.
prokopton
9 hours ago
If you want to maintain state across navigations and share that state with a server it’s the best we’ve got.
bpicolo
9 hours ago
Server can store session state
telgareith
9 hours ago
Server side session state for more than authentication is way worse than "code smell."
It requires a ping to a shared data source on every request. And, the same one for all of them. No sharding, No split domains... That gets expensive fast!
naasking
8 hours ago
You just described how the whole web operates. It works just fine.
MBCook
8 hours ago
Even if you want client side, we have better ways now than cookies.
inopinatus
3 hours ago
We do, but only cookies are universally available. Plenty of unusual user-agents in the world, or people like me that browse with JS off by default.
CrimsonRain
4 hours ago
I add some products in phone. Then I login to desktop later for modification and order. Cart is empty. That's engineering smell. A really bad one.
telgareith
2 hours ago
Thats nothing more than UX/UI.
> In computer programming, a code smell is any characteristic in the source code of a program that possibly indicates a deeper problem. Determining what is and is not a code smell is subjective, and varies by language, developer, and development methodology.