how to find user id from session_data from django_session table?

前端 未结 6 1669
粉色の甜心
粉色の甜心 2020-12-28 15:24

In django_session table session_data is stored which is first pickled using pickle module of python and then encoded in base64 by using base64 modu

6条回答
  •  长情又很酷
    2020-12-28 16:14

    If you want to learn more about it and know how does encode or decode work, there are some relevant code. By the way the version of Django that i use is 1.9.4.

    django/contrib/sessions/backends/base.py

    class SessionBase(object):
        def _hash(self, value):
            key_salt = "django.contrib.sessions" + self.__class__.__name__
            return salted_hmac(key_salt, value).hexdigest()
        def encode(self, session_dict):
            "Returns the given session dictionary serialized and encoded as a string."
            serialized = self.serializer().dumps(session_dict)
            hash = self._hash(serialized)
            return base64.b64encode(hash.encode() + b":" + serialized).decode('ascii')
        def decode(self, session_data):
            encoded_data = base64.b64decode(force_bytes(session_data))
            try:
                # could produce ValueError if there is no ':'
                hash, serialized = encoded_data.split(b':', 1)
                expected_hash = self._hash(serialized)
                if not constant_time_compare(hash.decode(), expected_hash):
                    raise SuspiciousSession("Session data corrupted")
                else:
                    return self.serializer().loads(serialized)
            except Exception as e:
                # ValueError, SuspiciousOperation, unpickling exceptions. If any of
                # these happen, just return an empty dictionary (an empty session).
                if isinstance(e, SuspiciousOperation):
                    logger = logging.getLogger('django.security.%s' %
                            e.__class__.__name__)
                    logger.warning(force_text(e))
                return {}
    

    django/contrib/sessions/serializer.py

    class JSONSerializer(object):
        """
        Simple wrapper around json to be used in signing.dumps and
        signing.loads.
        """
        def dumps(self, obj):
            return json.dumps(obj, separators=(',', ':')).encode('latin-1')
        def loads(self, data):
            return json.loads(data.decode('latin-1'))
    

    Let's focus on SessionBase's encode function.

    1. Serialize the session dictionary to a json
    2. create a hash salt
    3. add the salt to serialized session , base64 the concatenation

    So, decode is inverse. We can simplify the decode function in the following code.

    import json
    import base64
    session_data = 'YTUyYzY1MjUxNzE4MzMxZjNjODFiNjZmZmZmMzhhNmM2NWQzMTllMTp7ImNvdW50Ijo0fQ=='
    encoded_data = base64.b64decode(session_data)
    hash, serialized = encoded_data.split(b':', 1)
    json.loads(serialized.decode('latin-1'))
    

    And that what session.get_decoded() did.

提交回复
热议问题