Opened 16 years ago
Last modified 6 months ago
#10554 new New feature
Response.set_cookie should allow setting two cookies of the same name.
Reported by: | Jeremy Dunck | Owned by: | nobody |
---|---|---|---|
Component: | HTTP handling | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Since cookies have domain and path properties, this is a sensible thing to do:
response.set_cookie('x', path='/foo/', expires=<some expired date>) response.set_cookie('x', path='/bar/', expires=<some future date>)
It'd be nice if Django allowed this. Sadly, I think this would mean moving away from Cookie.
Change History (19)
comment:1 by , 16 years ago
comment:2 by , 16 years ago
milestone: | → 1.2 |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:3 by , 15 years ago
Owner: | changed from | to
---|
comment:4 by , 15 years ago
milestone: | 1.2 |
---|
1.2 is feature-frozen, moving this feature request off the milestone.
comment:5 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → New feature |
comment:8 by , 12 years ago
Owner: | changed from | to
---|---|
Version: | 1.0 → master |
comment:9 by , 11 years ago
Would a MorselKey class implementing the aforementioned methods in django.http.cookie be right? If so, I'll submit a patch.
comment:10 by , 11 years ago
I believe so, yes. Jacob accepted this ticket; there's been no debate on my suggested fix. I am now a core committer and feel this is a decent way to fix the problem.
I would point out that in the years since I wrote these notes, the versions of both django and supported python versions have changed - it's possible there's a better way now, though I don't have time to dig into it at the moment.
Thanks for your interest. :)
comment:11 by , 11 years ago
I have been fooling around with this little fix and one problem arises from the proposed solution: While the custom hash method prevents dict collisions, it also prevents from checking if some cookie already exists (as done by many contrib apps).
comment:12 by , 11 years ago
While a possible workaround could be to redefine SimpleCookie's method to check if some cookie exists, some structural issues would rise. What should we do if there're two cookies with the same name and SimpleCookie.get('cookie') is called?
MorselKey's could be used to grab cookies from cookies dict but a lot of external code would change.
comment:13 by , 11 years ago
comment:14 by , 11 years ago
We are currently getting a bug when a user has two sessionid cookies with different domains. The user then is completely unable to log in, getting redirected back to the homepage. It is related to this issue, but I'm not sure whether I should file a new ticket or not. I would suggest that, if the sessionid is expired, the cookies are deleted, but I'm not sure if it's actually expired or not. Login works, the user gets redirected to the root, and then the root sees that the user isn't authenticated and sends them back to login for ever. The user can only get out of this if they clear their cookies, which is a very significant bug.
comment:15 by , 9 years ago
The latest https://tools.ietf.org/html/rfc6265 says we should not do this, which makes me think it's not worth it. Is there a real-world problem that this would actually solve?
Servers SHOULD NOT include more than one Set-Cookie header field in the same response with the same cookie-name.
comment:16 by , 8 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Feel free to reopen if you think Django really needs this ability.
comment:17 by , 6 months ago
Resolution: | wontfix |
---|---|
Status: | closed → new |
This is some serious bug necromancy, but hear me out.
My CDN supports presigned URLs and presigned cookies. Presigned URLs negate client-side caching. Their presigned cookie implementation forbids specifying more than one approved asset per cookie.
This forces me to include multiple of these presigned cookies for my CDN's domain, with identical names, but paths for each asset, and to rely on the browser to use cookies' paths to identify which version of the cookie to send along with the request to the CDN.
Definitely an edge case, but worth bringing up as I can't find an escape hatch to force Django to otherwise include cookies with the same name and domain, but different paths.
comment:18 by , 6 months ago
Triage Stage: | Accepted → Unreviewed |
---|
comment:19 by , 6 months ago
Triage Stage: | Unreviewed → Accepted |
---|
With the concern from raised from RFC6265 as to whether we should do this, from what I read here: https://datatracker.ietf.org/doc/html/rfc6265#section-5.3
If the cookie store contains a cookie with the same name, domain, and path as the newly created cookie... [instructions on how to replace]
I see no issue in two cookie's with the same name and uniqueness should be determined by the combination of name, domain and path.
Based off how previously it was suggested this will be re-accepted providing there is a real world use-case, re-accepting.
OK, here's a plan for fix:
Currently, Django's response.cookies is an instance of stdlib's Cookie.SimpleCookie(BaseCookie).
BaseCookie is a subclass of dict, and so makes the assumption that there will be only one Morsel (that is, serializable cookie) per key. Key is assumed to be string, because BaseCookie does things like .lower and .translate on it, and therefore, there can only be one morsel per cookie name.
Here's the fix/hack: create a class which responds to the basestring methods, and takes all the HTTP-pertinent parameters (that is, name, path, domain, secure) into account for cmp and hash. Alter set_cookie to create an instance of that class as the key given to SimpleCookie. Respond to str with just the cookie name.