在django_session
表session_data
中存储,首先使用python的pickle模块进行pickle,然后使用python的base64模块在base64中进行编码。
我得到了解码的pickle session_data。
来自django_session表的session_data:
gAJ9cQEoVQ9fc2Vzc2lvbl9leHBpcnlxAksAVRJfYXV0aF91c2VyX2JhY2tlbmRxA1UpZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmRxBFUNX2F1dGhfdXNlcl9pZHEFigECdS5iZmUwOWExOWI0YTZkN2M0NDc2MWVjZjQ5ZDU0YjNhZA==
通过base64.decode(session_data)解码之后:
\x80\x02}q\x01(U\x0f_session_expiryq\x02K\x00U\x12_auth_user_backendq\x03U)django.contrib.auth.backends.ModelBackendq\x04U\r_auth_user_idq\x05\x8a\x01\x02u.bfe09a19b4a6d7c44761ecf49d54b3ad
我想从auth_user_id
中找出auth_user_idq\x05\x8a\x01\x02u
的价值
。请帮我这样做。
答案 0 :(得分:31)
我在使用Paulo的方法时遇到了麻烦(请参阅我对他的回答的评论),所以我最终使用scottbarnham.com blog post中的这个方法:
from django.contrib.sessions.models import Session
from django.contrib.auth.models import User
session_key = '8cae76c505f15432b48c8292a7dd0e54'
session = Session.objects.get(session_key=session_key)
uid = session.get_decoded().get('_auth_user_id')
user = User.objects.get(pk=uid)
print user.username, user.get_full_name(), user.email
答案 1 :(得分:11)
注意:自原始答案以来格式已更改,1.4及以上版本请参阅下面的更新
import pickle
data = pickle.loads(base64.decode(session_data))
>>> print data
{'_auth_user_id': 2L, '_auth_user_backend': 'django.contrib.auth.backends.ModelBackend',
'_session_expiry': 0}
[更新]
我的base64.decode需要文件名参数,所以我尝试了base64.b64decode,但这返回了“IndexError:list assignment index out of range”。
我真的不知道为什么我使用了base64模块,我猜是因为这个问题很有用。
您可以使用str.decode
方法:
>>> pickle.loads(session_data.decode('base64'))
{'_auth_user_id': 2L, '_auth_user_backend': 'django.contrib.auth.backends.ModelBackend',
'_session_expiry': 0}
我找到了解决办法(见下面的答案),但我很好奇为什么这不起作用。
从用户来源(cookies)加载腌制数据存在安全风险,因此自问题得到解答后,session_data格式发生了变化(我应该在Django的bug跟踪器中查找特定问题并将其链接到此处,但我的番茄钟休息时间是走了)。
现在的格式(自Django 1.4起)是“hash:json-object”,其中前40个字节的哈希是加密签名,其余是JSON有效载荷。现在你可以忽略哈希(它允许检查数据是否被某些cookie黑客篡改)。
>>> json.loads(session_data.decode('base64')[41:])
{u'_auth_user_backend': u'django.contrib.auth.backends.ModelBackend',
u'_auth_user_id': 1}
答案 2 :(得分:3)
from django.conf import settings
from django.contrib.auth.models import User
from django.utils.importlib import import_module
def get_user_from_sid(session_key):
django_session_engine = import_module(settings.SESSION_ENGINE)
session = django_session_engine.SessionStore(session_key)
uid = session.get('_auth_user_id')
return User.objects.get(id=uid)
答案 3 :(得分:3)
如果您想了解更多信息并了解编码或解码工作的方式,可以使用一些相关代码。 顺便说一句,我使用的Django版本是1.9.4。
的django /了contrib /会话/后端/ 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 /会话/ 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'))
让我们关注SessionBase的编码功能。
因此,解码是相反的。 我们可以在下面的代码中简化解码功能。
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'))
这就是session.get_decoded()所做的。
答案 4 :(得分:0)
我想使用最新版本的DJango(2.05)在纯Python中执行此操作。这就是我所做的:
>>> import base64
>>> x = base64.b64decode('OWNkOGQxYjg4NzlkN2ZhOTc2NmU1ODY0NWMzZmQ4YjdhMzM4OTJhNjp7Im51bV92aXNpdHMiOjJ9')
>>> print(x)
b'9cd8d1b8879d7fa9766e58645c3fd8b7a33892a6:{"num_visits":2}'
>>> import json
>>> data = json.loads(x[41:])
>>> print(data)
{'num_visits': 2}
答案 5 :(得分:0)
我只需要在Django安装上解决类似问题即可。我知道用户的ID(36),并想删除该特定用户的会话数据。我想将这段代码作为原型,用于在会话数据中查找用户。
from django.contrib.sessions.models import Session
TARGET_USER = 36 # edit this to match target user.
TARGET_USER = str(TARGET_USER) # type found to be a string
for session in Session.objects.all():
raw_session= session.get_decoded()
uid = session.get_decoded().get('_auth_user_id')
if uid == TARGET_USER: # this could be a list also if multiple users
print(session)
# session.delete() # uncomment to delete session data associated with the user
希望这对在那里的人有帮助。