Opened 15 years ago

Last modified 2 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 Jeremy Dunck, 15 years ago

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.

comment:2 by Jacob, 15 years ago

milestone: 1.2
Triage Stage: UnreviewedAccepted

comment:3 by ccahoon, 15 years ago

Owner: changed from nobody to ccahoon

comment:4 by James Bennett, 14 years ago

milestone: 1.2

1.2 is feature-frozen, moving this feature request off the milestone.

comment:5 by Chris Beaven, 13 years ago

Severity: Normal
Type: New feature

comment:6 by Aymeric Augustin, 12 years ago

UI/UX: unset

Change UI/UX from NULL to False.

comment:7 by Aymeric Augustin, 12 years ago

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:8 by Aymeric Augustin, 12 years ago

Owner: changed from ccahoon to nobody
Version: 1.0master

comment:9 by Unai Zalakain, 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 Jeremy Dunck, 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 Unai Zalakain, 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 Unai Zalakain, 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:14 by Stavros Korokithakis, 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 Collin Anderson, 8 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 Collin Anderson, 8 years ago

Resolution: wontfix
Status: newclosed

Feel free to reopen if you think Django really needs this ability.

comment:17 by Benjamin Vulpes, 2 months ago

Resolution: wontfix
Status: closednew

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 Claude Paroz, 2 months ago

Triage Stage: AcceptedUnreviewed

comment:19 by Sarah Boyce, 2 months ago

Triage Stage: UnreviewedAccepted

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.

Note: See TracTickets for help on using tickets.
Back to Top