2010-11-04 10 views
15

django_session तालिका session_data संग्रहीत किया जाता है जिसे पहले पाइथन के अचार मॉड्यूल का उपयोग करके चुना जाता है और फिर पायथन के बेस 64 मॉड्यूल का उपयोग करके बेस 64 में एन्कोड किया जाता है।django_session तालिका से 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_idq\x05\x8a\x01\x02u से auth_user_id पता लगाना चाहते हैं। कृपया ऐसा करने में मेरी मदद करें।

उत्तर

25

मैं पाउलो की विधि में समस्या आई (अपने जवाब पर मेरी टिप्पणी देखें), तो मैं एक 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 
10

नोट: प्रारूप 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} 

[अद्यतन]

My base64.decode requires filename arguments, so then I tried base64.b64decode, but this returned "IndexError: list assignment index out of range".

मैं वास्तव में मैं क्यों बेस 64 मॉड्यूल का इस्तेमाल किया पता नहीं है, मुझे लगता है क्योंकि सवाल यह दिखाया गया है। उपयोगकर्ता स्रोतों से

>>> pickle.loads(session_data.decode('base64')) 
{'_auth_user_id': 2L, '_auth_user_backend': 'django.contrib.auth.backends.ModelBackend', 
'_session_expiry': 0} 

I found a work-around (see answer below), but I am curious why this doesn't work.

लोड हो रहा है मसालेदार डेटा (कुकीज़) एक सुरक्षा जोखिम है, इसलिए session_data प्रारूप बदल गया था के बाद से इस सवाल का जवाब दिया गया था (मैं चाहिए:

तुम बस str.decode विधि का उपयोग कर सकते हैं Django के बग ट्रैकर में विशिष्ट समस्या के बाद जाएं और इसे यहां लिंक करें, लेकिन मेरा पोमोडोरो ब्रेक चला गया है)।

अब प्रारूप (क्योंकि Django 1.4) "हैश: जेसन-ऑब्जेक्ट" है, जहां पहला 40 बाइट हैश एक क्रिप्टो-हस्ताक्षर है और बाकी एक JSON पेलोड है। अभी के लिए आप हैश को अनदेखा कर सकते हैं (यह जांचता है कि डेटा को कुछ कुकी हैकर द्वारा छेड़छाड़ नहीं किया गया था)।

>>> json.loads(session_data.decode('base64')[41:]) 
{u'_auth_user_backend': u'django.contrib.auth.backends.ModelBackend', 
u'_auth_user_id': 1} 
+0

यह पाइथन 2.7 और Django 1.4 का उपयोग कर मेरे लिए काम नहीं करेगा। मेरे 'base64.decode' को फ़ाइल नाम तर्क की आवश्यकता है, इसलिए मैंने' base64.b64decode' को आजमाया, लेकिन यह "इंडेक्स एरर: सूची असाइनमेंट इंडेक्स सीमा से बाहर" लौटा। मुझे एक काम-आसपास मिला (नीचे जवाब देखें), लेकिन मुझे उत्सुकता है कि यह क्यों काम नहीं करता है। –

+1

@ डोलन: अद्यतन उत्तर देखें, सुरक्षा चिंताओं के कारण सत्र_डेटा प्रारूप बदल गया। –

2
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) 
1

आप के बारे में अधिक जानने के लिए चाहते हैं यह और पता है कि कैसे एन्कोड या डीकोड काम करता है, कुछ प्रासंगिक कोड हैं। जिस तरह से मैं उपयोग करता हूं Django का संस्करण 1.9.4 है।

Django/योगदान/सत्र/बैकेंड/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/योगदान/सत्र/serializer.py SessionBase के एनकोड समारोह पर

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

आइए फोकस।

  1. एक json
  2. को सत्र शब्दकोश को क्रमानुसार एक हैश नमक
  3. बनाने धारावाहिक सत्र के लिए नमक जोड़ने के लिए, संयोजन

तो, डिकोड उल्टा होता है Base64। हम निम्नलिखित कोड में डीकोड फ़ंक्शन को सरल बना सकते हैं।

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

और वह सत्र.get_decoded() ने किया।