With Django sessions, there are some cases where the encoded session data stored in the database can not be decoded using django.contrib.sessions.models.Session
's get_decoded
method, i.e. it will always return an empty dictionary.
Is there any way to decode that data?
It relies on django.contrib.sessions.backends.base.SessionBase
's decode
method, which will return an empty dictionary if a calculated hash is different from an expected hash (it raises a SuspiciousOperation
exception).
django.contrib.sessions.models.Session
's get_decoded
method relies on django.contrib.sessions.backends.base.SessionBase.decode
, which will return an empty dictionary if a calculated hash is different from an expected hash (it raises a SuspiciousOperation
exception), there is a ValueError
or unpickling exceptions. It will catch all exceptions really, but those are the reasons the code can fail.
So, wrapping all those code calls together except the hash checking part, you can get what you need. Below there is a function that will give you the decoded session data of a certain session object, provided that it exists.
import base64
import pickle
from django.contrib.sessions.models import Session
from django.utils.encoding import force_unicode
def decode_session_data(session_key):
"""Decode the data in a session object stored under ``session_key``.
:param session_key: e.g. ``'1180b5ed42c2a3a5f217e35b755865da'``
:return: decoded session data
:rtype: :class:`dict`
"""
session_obj = Session.objects.get(pk=session_key)
session_data = force_unicode(session_obj.session_data)
encoded_data = base64.decodestring(session_data)
hash, pickled = encoded_data.split(':', 1)
return pickle.loads(pickled)
source: https://gist.github.com/3982485, based on source code from the Django project.