Si desea obtener más información sobre y sabe cómo codifica o decodifica el trabajo, hay algún código relevante. Por cierto, la versión de Django que uso es 1.9.4.
django/contrib/sesiones/backend/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/sesiones/serializer.py enfoque
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'))
Vamos en la función de codificación de SessionBase.
- serializar el diccionario sesión a un JSON
- crear una sal de hash
- añadir la sal a la sesión serializado, Base64 la concatenación
Así, decodificar es inversa. Podemos simplificar la función de decodificación en el siguiente código.
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'))
Y eso que session.get_decoded() hizo.
Esto no funcionaría para mí usando Python 2.7 y Django 1.4. Mi 'base64.decode' requiere argumentos de nombre de archivo, entonces probé' base64.b64decode', pero esto devolvió "IndexError: índice de asignación de lista fuera de rango". Encontré una solución alternativa (ver respuesta a continuación), pero tengo curiosidad de por qué esto no funciona. –
@dolan: vea la respuesta actualizada, el formato session_data ha cambiado debido a problemas de seguridad. –