Code

Opened 8 months ago

Closed 8 months ago

Last modified 8 months ago

#20922 closed New feature (fixed)

Allow customizing the serializer used by contrib.sessions

Reported by: gwahl@… Owned by: timo
Component: contrib.sessions Version: 1.5
Severity: Release blocker Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by timo)

The django.contrib.sessions.backends.signed_cookies session backend should be written in a way that allows subclasses to use their own serializer implementation. This will allow using JSON instead of Pickle to serialize sessions.

For background, see #20444 and https://groups.google.com/d/topic/django-developers/YwlZ9m9k1bE/discussion.

Attachments (0)

Change History (8)

comment:1 Changed 8 months ago by gwahl@…

  • Has patch set
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Pull request: https://github.com/django/django/pull/1474

Question: Should this be mentioned in the docs for this backend? An example of a backend using JSON could be helpful.

comment:2 Changed 8 months ago by timo

  • Component changed from Uncategorized to contrib.sessions
  • Severity changed from Normal to Release blocker
  • Triage Stage changed from Unreviewed to Accepted
  • Type changed from Uncategorized to New feature

Yes, I actually have a more extensive patch in the works.

comment:3 Changed 8 months ago by timo

  • Description modified (diff)
  • Owner changed from nobody to timo
  • Status changed from new to assigned
  • Summary changed from Signed Cookie Session Backend Should Support Using a JSON Serializer to Allow customizing the serializer used by contrib.sessions

The plan is to introduce settings.SESSION_SERIAZLIER in the next 1.5.x release. It'll default to using pickle for backwards compatibility, but the default will switch to using JSON in 1.6. Pull request in progress.

An additional API has been proposed by @apollo13 to allow customizing the serializiers a bit easier (rather than dealing with subclassing the current serializers, having to possibly write mixins, etc.). For example, in the existing patch JSONMessagesSerializer could be replaced by a hook:

class SerializerHook(object):
  handles_variables = ['variable1', ...]

  def to_primitive(self, name, object):
      pass

 def from_primitive(self, name, object):
     pass

Then in settings.py you'd have another setting:

SESSION_SERIALIZER_HOOKS = ['django.contrib.messages.session_hook', ...]

This would allow 3rd party applications to provide simple hooks for their session stuff (although that should be rare since you generally don't put that much logic into sessions, messages are one example of where you still might wanna do it).

Feedback on whether or not this additional complexity is worthwhile would be appreciated.

comment:4 Changed 8 months ago by akaariai

I think the additional complexity is needed. If you happen to use two different applications that use something more complex in sessions, you will need that.

Some questions:

  • Are model instances automatically serializable? I know they can be serialized for fixtures...
  • What if two hooks have same "handles_variables" keys? First one wins? Chain them? ValidationError? Something else?
  • If you have some object type that needs always custom serialization, but is found from different names in the session, is there any nice way to handle that using the above API? Maybe '*' variable? Or maybe there should be object hook that will be called if present (json_serialize(), json_deserialize() for example).
  • What about nested structures, if you happen to have object you know how to serialize deeply nested, how to proceed? Again object hooks would help here.
  • What happens when transitioning from Pickle to JSON? Loud failure seems like bad option, throwing session data out seems OK. I think this should be tested (unless it already is).

These are not meant to be "must fix" issues, it is completely OK to answer "too complex" to some of them... In any case there will be use cases where JSON serialization will be nearly impossible. QuerySet serialization comes to mind here...

comment:5 Changed 8 months ago by timo

  1. No, model instances are not serializable using JSON. Its limitations are noted in the documentation. An application would be responsible for serializing the instance before storing it in a session.
  2. We're not planning implementing the "hook" idea.
  3. N/A, we're not implementing this API.
  4. As hinted to above, our design decision boiled down to "it's up to the application to only store simple data structures in sessions." See the changes to contrib.messages for an example.
  5. Sessions will be dropped (the release notes for 1.6 and 1.5.3 will mention this). SessionBase.decode catches deserialization exceptions and returns an empty session.

comment:6 Changed 8 months ago by Tim Graham <timograham@…>

  • Resolution set to fixed
  • Status changed from assigned to closed

In b0ce6fe656873825271bacb55e55474fc346c1c6:

Fixed #20922 -- Allowed customizing the serializer used by contrib.sessions

Added settings.SESSION_SERIALIZER which is the import path of a serializer
to use for sessions.

Thanks apollo13, carljm, shaib, akaariai, charettes, and dstufft for reviews.

comment:7 Changed 8 months ago by Tim Graham <timograham@…>

In 616a4d385a79d6809b618dcc8bcbda05b032d5fc:

[1.5.x] Fixed #20922 -- Allowed customizing the serializer used by contrib.sessions

Added settings.SESSION_SERIALIZER which is the import path of a serializer
to use for sessions.

Thanks apollo13, carljm, shaib, akaariai, charettes, and dstufft for reviews.

Backport of b0ce6fe656 from master

comment:8 Changed 8 months ago by Tim Graham <timograham@…>

In 5f061986b9903b335e4bfe41cf172d710604d5cb:

[1.6.x] Fixed #20922 -- Allowed customizing the serializer used by contrib.sessions

Added settings.SESSION_SERIALIZER which is the import path of a serializer
to use for sessions.

Thanks apollo13, carljm, shaib, akaariai, charettes, and dstufft for reviews.

Backport of b0ce6fe656 from master

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.