Question

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).

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top